Why Every Computer Fails Basic Math

Web Dev Simplified · Beginner ·🌐 Frontend Engineering ·2y ago

Key Takeaways

Explains why computers fail at basic math operations like adding 0.1 and 0.2 due to binary representation

Full Transcript

we all know that 0.1 + 2 is equal to. 3 except JavaScript for some reason thinks this is 300004 but why exactly is it that JavaScript and actually all computers and all programming languages get this simple question wrong that's what I'm going to explain in this video we're going to go super deep into the Leeds of how computers work behind the scenes to figure out why this is actually a problem and I'm going to talk to you about why this is an important thing for you to understand to make sure that you write correct and bug free code in the future because if you don't understand this concept you're bound to make mistakes in your code welcome back to web dev simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream project sooner and in this video I want to be get started by talking about why this actual problem exists then I'm going to go into practical reasons why it's important before finally at the very end doing a super nerdy Deep dive into exactly how computers actually render and manipulate numbers so the very first thing we need to understand before we start applying this to our actual real world programming is how do we actually convert numbers to Binary and binary is just the way that computers represent numbers so normally if we were to write out a number for example if we write out 20 or maybe like 34 or 120 or 1230 whatever it is we write out a number like this it makes perfect sense but computers have to write out numbers in binary they only have access to ones and zeros so for example if we wanted to write out the number eight in binary it would look like this 1 0 0 the number nine would be 1 0 0 1 this this is how computers actually render out and use numbers to be able to do different math operations so for us to understand why computers get 0.1 plus2 wrong we need to understand how they convert from decimal numbers which is what we're used to to these more binary style numbers so let's say we want to write out the binary number for six we want to convert six into binary well the easy way to do this is just take our number six and we divide it by two and as you can see when we divide this by two we get three there's no decimal points or nothing like that you can see that this divide super cleanly so when that happens we just write down a zero for our place here for the binary number then we just divide by two again so 3 divid by two that is equal to 1.5 anytime that we get a decimal place when we're doing this conversion we write down a one in our number and you can see we're writing this down from right to left so the first thing was on the right our one is going to be the next and all we do is we just get rid of the decimal portion so we're left with just our number one so we take our number one divide two that's going to give us .5 which is again a decimal point so we write down a one in our binary number get rid of the decimal point section and we're left with zero which means we're done with our conversion and now we have the binary representation of six which is 1 1 0 now the way that this binary representation works is essentially it represents powers of two so this first number here is 2 to the power of two this next number here is 2 to the power of 1 and this final number is 2 to the power of0 so all we do is we just take 2^ of 2 plus 2^ of 1 plus plus 2^ 0 and multiply it by these numbers so we're taking 1 of 2 to the^ of two we're taking 1 of 2 the^ of 1 and we're taking 0 of 2 the^ of 0 so essentially we're doing 4 + 2 + 0 obviously that gives us out 6 as our answer try the exact same thing with a different number so let's just delete all of this and say this time instead we're going to be doing the number five so we can come in here draw out the number five divide it by 2 and we're going to get 2.5 this is a decimal point so we're going to place down a one remove the decimal divide 2 that's going to give us 1 so there's no decimal point here we're going to put down a zero again divide 2 we get .5 remove the decimal and place down a one and now we're left with zero which means we're done with our operation so 5 is 1 1 again we get 2 the 2 plus and this is a zero so we ignore it and then 2 to the 0 so we just get 4 + 1 which obviously is equal to 5 so we can see that our math is actually working and we're able to convert these numbers back and forth this is essentially what a computer does when you write down the number five inside of your JavaScript code it's essentially rendering that as 101 now when it comes to decimal point numbers the system is very similar let's say we wanted to take the number 75 and we wanted to convert this to the binary representation well the way we would do this is instead of dividing by two we would multiply by two so what we can do is we can take 75 * 2 and that's going to give us the number of 1.5 so anytime you're trying to convert a fractional number when you multiply by two if you have a value greater than one what you do is you write down a one for that place inside of your actual binary you remove the one and then continue on so here we have 0. five we multiply by two and that gives us the value of one so we can write down one just like that and you'll notice in this case I'm actually going from left to right instead of right to left so that's one thing to keep in mind now we remove the one and we're left over with zero so we know we're completely done and you can see here 75 is equal to11 inside of binary and the way that this works when we convert from binary to decimal is this first number is going to be 2 to the power of 1 but it's going to be a fraction so it's 1 / 2 ^ 1 the next one is going to be 1/ 2 to the^ of 2 so essentially we have .5 +25 which is equal to 75 that makes sense now if we wanted to try out a different number let's say that we're going to do here the number of 0.1 this is the number that we've already talked about before so here we go we have 0.1 well we multiply this by two and you can see we're going to get two that makes sense so we write down a zero because this is not greater than one then we continue on multiply this by two we get4 again not greater than zero so we write down zero multiply by two we get 8 and we write down a zero again finally multiply by two and we get 1.6 this is greater than one so we write down a one get rid of the one and now we're left with 6 I'll just bring it up here so 6 * 2 = 1.2 you can see here greater than 1 so we write down one remove this and now we're left with 2 2 * 2 is equal to4 and you'll notice something really interesting right here things are starting to repeat I already did 2 * 2 is equal to4 right here which means no matter what I do this number is going to infinitely repeat inside of a loop where I'm constantly writing down essentially the exact same thing over and over I'm going to get 0 0 1 1 0 0 1 1 0 0 1 1 over and over and over and over again all the way until Infinity this is obviously a problem because we don't have Infinite Space to store this number so at some point JavaScript needs to say you know what I'm done calculating these are all the different digits that I can store I cannot store anything else so it's going to get a representation that's as close as possible to 0.1 but obviously it's not going to be exactly 0.1 it's the exact same problem with Point 2 as you can see 0 2 has that same repeating problem so when we try to write out 0 2 inside of an actual binary format we're going to be getting a problem because again it cannot perfectly represent that because in binary 0.1 and 2 are infinitely repeating numbers this is something that you're probably familiar with all the time inside of normal decimal numbers because if we do something like 1 / 9 if we try to write that out as a decimal number that's just 0.111 one11 one11 forever and ever the one just constantly repeats forever and ever and ever that's the exact same thing with 0.1 and 0 2 inside a decimal they just repeat forever and ever so there at some point you need to make a cut off value this is essentially what is happening when we try to do the 0.1 plus 2 if we do right here .1 + 2 is equal to. 3 the reason the computer gets this wrong is because 0.1 and 2 both infinitely repeat so they essentially have to be rounded just a little bit to be as close as possible which is why this final number of. 3 ends up with something like this when you actually do the conversion now the reason this is important to understand is because of how it actually interacts with the code that you write inside of your editor because anytime you're dealing with numbers that have decimal point you need to be very careful with how you write your code let's take a look at an example of this as you can see I have some very simple code all I'm doing is setting a score variable to zero and I have a function that every time I call it I add 0.1 to my score and then I'm just checking whenever my score is equal to one I console log you win Super straightforward code you'll think after I call this function 10 times the score will be equal to one and it'll log out you win so let's see if that actually is the case we'll come over into here and I'm just going to call that add score function we can even check to see that our score is currently set to zero so I'll call add score and make sure that I actually call this as a function and you can see if I call this a couple times we can check what our score is equal to we're currently at4 so let me just call this a couple more times and you'll notice I've called this enough times that it should have logged. i1 but at no point has it actually logged out that I won and if we check our score variable you'll notice that it currently has some rounding problems it's 1.96 so clearly there's some rounding errors going on inside of this because of the fact we're adding 0.1 and 0 2 and such on numbers and these numbers have to be rounded because they're in binary and they can't be represented perfectly so whenever you're dealing with floating point Point numbers essentially a decimal point number you always want to make sure that you use less than or equal to and you never actually use this full on equal equal equal symbol to do these comparisons for example I want to check when the score is greater than or equal to 1 now it'll make sure that this will always render as soon as my score gets to one or greater and that'll hopefully help account for some of the rounding problems I had what you could also do is you could come in here and manually round this number based on whatever rounding system you want to use but this is going to be one of the easiest ways to just make sure that it's always going to be above that threshold especially if you're adding really small numbers like you're constantly adding really really small numbers to this and you just want to check when it eventually goes over this one value that's going to be a really great way to check for these particular things so now if we change this back here to 0.1 we can go into our code and check to see if this works so if we pull over our code we can check our score is currently zero and if I come in here and I call add score I'm just going to call this function a bunch of times and eventually we should get to the point where we've called it enough times and you can see now it is printing out you win because we are greater than that one number for our score and if I check our score you can see it's currently at 1.2 so really the main takeaway from all this learning is that whenever you're dealing with floating Point numbers you always want to make sure you never check for exactly equality because most likely there's going to be rounding errors and it won't actually always equal this number sometimes you may get lucky and it'll work but other times you're going to run into problems where you have rounding errors and it will not work so using something like greater than or less than is the great option now I want to get a little bit nerdier and deep dive even further into how numbers are represented in computers because pretty much every programming language and computer out there represents numbers in the exact same way so if we go back over to here we can see that we have this code I'm just going to get rid of everything inside of here there we go and whenever you're dealing with computers numbers that are floating Point numbers especially are generally going to be represented with three separate parts you're going to have these three parts that look like this and then finally the largest part at the end so this first part is just going to be either a z 0 or one it's one single binary digit and this represents the sign is it a positive number or is it a negative number if you put a one there that means it's a negative number a zero means it is a positive number so this is just a super simple sign bit that tells you positive versus negative the next thing that we're going to have is going to be our exponent let me move that up a little bit so it's a little bit easier to read There we go our exponent and this is essentially going to be two to a certain power so it'll be like 2 to the 4th or 2 the 10th or maybe it be 2 to the - 100th it's going to be some form of exponent that we can use to represent what we want to multiply the rest of our number by and then finally we have this very last section this last section is called the mantisa and essentially this is just a decimal point number that we multiply by the exponent over here so this might be something like 0.1 or like 3 4 doesn't matter what it is it is some decimal point number and obviously it's represented in binary so so it'll be like 1 0 0 0 1 1 1 0 something like that that represents a decimal point number and the way that we work with this is we take this decimal point number and we multiply it by whatever this 2 to the exponent is so 2 to -00 times this decimal point number is going to give us the exact number that we're looking for now depending on how your numbers are stored some programming languages use larger or smaller sizes to store these floating Point numbers so you may have like a 16bit or a 32-bit number being represented by this now if we go ahead there's actually a calculator that you can use I'm going to leave this in the description for you a link to this exact page but essentially this is showing a calculator for how it's actually calculate out as you can see we have our sign bit at the very beginning you can see when it is a zero it is positive and when it's a negative it's a negative number right there then we have our exponent and this exponent you can see is eight total bits that it can be calculated from so you can see here this is eight bits and then we finally have our actual mantisa which is that decimal point number and if we do the math on this it looks like it's being calculated from 20 three different digits so in total this is a 32bit floating Point number because we have 23 bits for the mantisa eight bits for the exponent one bit for the sign you add that together we get 32 bit if you had a 64-bit number essentially this exponent section and this mantisa section would be larger giving you a wider range of numbers that you could represent now the nice thing about this calculator is I can type in any decimal point number here and it's going to show me exactly how this is represented in binary so let's say that I wanted to do the number 456 and I just clicked off of this you can see that my exponent has been set to 2 to the^ of 8 and my mantisa here has been set to 78125 and if we do the multiplication of those numbers together we're going to get exactly 456 now the reason that numbers are stored this way instead of being stored as just raw binary so like for example we don't just write out the raw binary of the number we write it out like this is because it gives us a much wider range of numbers that we can actually represent especially when we start dealing with decimal point numbers for example if I add in like 243 to the end of this you can now see based on this mantisa and this exponent here I get a very wide range of numbers that I can represent now if we real quickly reset this back to zero we can see some interesting things about how this actually works you'll notice that the exponent starts out as -126 by default this allows us to represent incredibly small decimal point numbers and if we wanted to represent a positive number as you can see as soon as I click this very first checkbox here that's going to give me exactly two to the very first power so this is how I represent more larger numbers anything larger than zero if I want to represent something less than zero I can use essentially this default of -26 or I can check as many of these as I need to actually make sure I'm getting the exact number I need so for example if I were to come in here and I said that I wanted to do like 0.123 and I did enter on this you can see here it's 2 to the4 with this 968 as the actual mantisa portion now I mentioned how this technique allows you to actually offer a wider range of numbers including decimal point numbers and to prove that that is the case I just want to show you exactly what the difference looks like so if we represent just a normal binary number the absolute largest binary number that we can represent using 32 bits is going to be this number 4294967296 it's a very large number but it doesn't give us nearly the range as a floating point would as you can see here a single Precision floating Point number which is 32 bit allows us to represent essentially the smallest number of 3.4 to the power of the 38th so 10 to the 38th or it allows us to represent a positive number of essentially the exact same size 3.4 all the way to e to 38 it also lets us represent numbers as small as e to the - 38 so 10 to the - 38 power and allows us to represent all those decimal point representations in between well if we just did a normal 2 to the 32nd that does not allow any decimal point numbers or negatives or anything at all like that so it's very restrictive in comparison now obviously the downside to these floating Point numbers in comparison to an integer-based approach is that the floating Point numbers will have rounding errors in many cases where it cannot be perfectly represented in binary for example 0.1 and0 two while this integer approach will never have any rounding errors because we're not actually doing any rounding at all in our binary and it's a positive integer based number which can always be represented perfectly in binary as long as you have enough digits inside of your binary to do so now it's not super important that you understand the exact underlying reason behind why this calculator works and how everything is represented because this is incredibly low-l stuff and even myself I don't exactly 100% understand exactly how this will look but understanding that fractional numbers inside of any computer programming language will be represented in binary which means that they may not always be able to be perfectly represented for example they may be rounded in certain scenarios means that you need to make sure whenever you're using a floating Point number in your code that you make sure you're mentally aware of this and that you never check exact equality of any number that could be fractional now that is a wild Deep dive that we went on to understand these Concepts and if you're still watching that's incredible more power to you I figured I should probably put my computer engineering degree to use and actually explain some of these lower level Concepts if you enjoyed this video and really like the lower level Deep dive into why things work behind the scenes let me know down in the comments below and I can make more videos like this if you're interested and want more with that said thank you very much for watching and have a good day

Original Description

It is a meme at this point that JavaScript sucks since it cannot even add 0.1 and 0.2 correctly. This is true, but it is not a problem with JavaScript. This is a problem with every single programming language and every single computer ever developed since they all use binary for their calculations which is why computers fail to add this correctly. In this video I will show you why this problem exists, then show you why it is important to you, before finally wrapping up with a nerdy deep dive into how computers handle floating point numbers. 📚 Materials/References: IEEE 754 Calculator: https://www.h-schmidt.net/FloatConverter/IEEE754.html 🌎 Find Me Here: My Blog: https://blog.webdevsimplified.com My Courses: https://courses.webdevsimplified.com Patreon: https://www.patreon.com/WebDevSimplified Twitter: https://twitter.com/DevSimplified Discord: https://discord.gg/7StTjnR GitHub: https://github.com/WebDevSimplified CodePen: https://codepen.io/WebDevSimplified ⏱️ Timestamps: 00:00 - Introduction 00:58 - Binary Integers 04:04 - Binary Decimals 05:17 - The Problem With 0.1 + 0.2 07:56 - Why This Is Important 10:26 - Nerdy Deep Dive #Binary #WDS #JavaScript
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Web Dev Simplified · Web Dev Simplified · 0 of 60

← Previous Next →
1 Introduction to Web Development || Setup || Part 1
Introduction to Web Development || Setup || Part 1
Web Dev Simplified
2 Introduction to Web Development || Understanding the Web || Part 2
Introduction to Web Development || Understanding the Web || Part 2
Web Dev Simplified
3 Introduction to HTML || Your First Web Page || Part 1
Introduction to HTML || Your First Web Page || Part 1
Web Dev Simplified
4 Introduction to HTML || Basic HTML Elements || Part 2
Introduction to HTML || Basic HTML Elements || Part 2
Web Dev Simplified
5 Introduction to HTML || Advanced HTML Elements || Part 3
Introduction to HTML || Advanced HTML Elements || Part 3
Web Dev Simplified
6 Introduction to HTML || Links and Inputs || Part 4
Introduction to HTML || Links and Inputs || Part 4
Web Dev Simplified
7 Learn Git in 20 Minutes
Learn Git in 20 Minutes
Web Dev Simplified
8 5 Must Know Sites For Web Developers
5 Must Know Sites For Web Developers
Web Dev Simplified
9 10 Best Visual Studio Code Extensions
10 Best Visual Studio Code Extensions
Web Dev Simplified
10 Learn CSS in 20 Minutes
Learn CSS in 20 Minutes
Web Dev Simplified
11 How to Style a Modern Website (Part One)
How to Style a Modern Website (Part One)
Web Dev Simplified
12 How to Style a Modern Website (Part Two)
How to Style a Modern Website (Part Two)
Web Dev Simplified
13 3D Flip Button Tutorial
3D Flip Button Tutorial
Web Dev Simplified
14 How to Style a Modern Website (Part Three)
How to Style a Modern Website (Part Three)
Web Dev Simplified
15 Animated Loading Spinner Tutorial
Animated Loading Spinner Tutorial
Web Dev Simplified
16 How to Write the Perfect Developer Resume
How to Write the Perfect Developer Resume
Web Dev Simplified
17 Animated Text Reveal Tutorial
Animated Text Reveal Tutorial
Web Dev Simplified
18 Learn Flexbox in 15 Minutes
Learn Flexbox in 15 Minutes
Web Dev Simplified
19 Custom Checkbox Tutorial
Custom Checkbox Tutorial
Web Dev Simplified
20 Start Contributing to Open Source (Hacktoberfest)
Start Contributing to Open Source (Hacktoberfest)
Web Dev Simplified
21 JavaScript Shopping Cart Tutorial for Beginners
JavaScript Shopping Cart Tutorial for Beginners
Web Dev Simplified
22 Responsive Video Background Tutorial
Responsive Video Background Tutorial
Web Dev Simplified
23 1,000 Subscriber Giveaway
1,000 Subscriber Giveaway
Web Dev Simplified
24 How To Prevent The Most Common Cross Site Scripting Attack
How To Prevent The Most Common Cross Site Scripting Attack
Web Dev Simplified
25 Transparent Login Form Tutorial
Transparent Login Form Tutorial
Web Dev Simplified
26 The Forgotten CSS Position
The Forgotten CSS Position
Web Dev Simplified
27 How to Code a Card Matching Game
How to Code a Card Matching Game
Web Dev Simplified
28 10 Must Install Visual Studio Code Extensions
10 Must Install Visual Studio Code Extensions
Web Dev Simplified
29 Learn CSS Grid in 20 Minutes
Learn CSS Grid in 20 Minutes
Web Dev Simplified
30 Learn JSON in 10 Minutes
Learn JSON in 10 Minutes
Web Dev Simplified
31 10 Essential Keyboard Shortcuts For Programmers
10 Essential Keyboard Shortcuts For Programmers
Web Dev Simplified
32 What Is The Fastest Way To Load JavaScript
What Is The Fastest Way To Load JavaScript
Web Dev Simplified
33 Differences Between Var, Let, and Const
Differences Between Var, Let, and Const
Web Dev Simplified
34 How To Install MySQL (Server and Workbench)
How To Install MySQL (Server and Workbench)
Web Dev Simplified
35 Learn SQL In 60 Minutes
Learn SQL In 60 Minutes
Web Dev Simplified
36 How To Solve SQL Problems
How To Solve SQL Problems
Web Dev Simplified
37 What Are Design Patterns?
What Are Design Patterns?
Web Dev Simplified
38 Null Object Pattern - Design Patterns
Null Object Pattern - Design Patterns
Web Dev Simplified
39 Your First Node.js Web Server
Your First Node.js Web Server
Web Dev Simplified
40 How To Setup Payments With Node.js And Stripe
How To Setup Payments With Node.js And Stripe
Web Dev Simplified
41 How To Learn Any New Programming Skill Fast
How To Learn Any New Programming Skill Fast
Web Dev Simplified
42 Asynchronous Vs Synchronous Programming
Asynchronous Vs Synchronous Programming
Web Dev Simplified
43 JavaScript ES6 Arrow Functions Tutorial
JavaScript ES6 Arrow Functions Tutorial
Web Dev Simplified
44 Are You Too Old To Learn Programming?
Are You Too Old To Learn Programming?
Web Dev Simplified
45 JavaScript Cookies vs Local Storage vs Session Storage
JavaScript Cookies vs Local Storage vs Session Storage
Web Dev Simplified
46 JavaScript Promises In 10 Minutes
JavaScript Promises In 10 Minutes
Web Dev Simplified
47 Builder Pattern - Design Patterns
Builder Pattern - Design Patterns
Web Dev Simplified
48 JavaScript == VS ===
JavaScript == VS ===
Web Dev Simplified
49 JavaScript ES6 Modules
JavaScript ES6 Modules
Web Dev Simplified
50 8 Must Know JavaScript Array Methods
8 Must Know JavaScript Array Methods
Web Dev Simplified
51 CSS Variables Tutorial
CSS Variables Tutorial
Web Dev Simplified
52 JavaScript Async Await
JavaScript Async Await
Web Dev Simplified
53 How To Choose Your First Programming Language
How To Choose Your First Programming Language
Web Dev Simplified
54 Easiest Way To Work With Web Fonts
Easiest Way To Work With Web Fonts
Web Dev Simplified
55 Singleton Pattern - Design Patterns
Singleton Pattern - Design Patterns
Web Dev Simplified
56 Responsive Navbar Tutorial
Responsive Navbar Tutorial
Web Dev Simplified
57 CSS Progress Bar Tutorial
CSS Progress Bar Tutorial
Web Dev Simplified
58 Learn GraphQL In 40 Minutes
Learn GraphQL In 40 Minutes
Web Dev Simplified
59 What is an API?
What is an API?
Web Dev Simplified
60 Learn How To Build A Website In 1 Hour!
Learn How To Build A Website In 1 Hour!
Web Dev Simplified

Related Reads

Chapters (6)

Introduction
0:58 Binary Integers
4:04 Binary Decimals
5:17 The Problem With 0.1 + 0.2
7:56 Why This Is Important
10:26 Nerdy Deep Dive
Up next
How to Speed Up Your WordPress Website with WP Rocket ⚡Tutorial 2026
Matt Tutorials
Watch →