Download presentation
Presentation is loading. Please wait.
1
Floating Point Numbers
or Why Javascript Is Bad At Math Format/timing of meetup About 15min presentation The rest of the time is open for general questions, homework help, networking Summary of this talk and take aways Javascript is bad at decimal math (financial and scientific math) Here are the technical reasons Slideshow and more detailed article available at
2
Javascript stores all numbers as floating point numbers.
Other languages support several number data types Such as Integer and Fixed Point Number C# has 12 different number data types Bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal
3
Integer Fixed Point Number (with 3 decimal places)
, -35, -1, 0, 1, 24, 28995, Fixed Point Number (with 3 decimal places) , , , 0.000, 1.000, , Floating Point Number , -35.4, -1.0, 0.0, 1.0, , , Integers are whole numbers Fixed Point Numbers are decimals with a consistent number of digits before and after the decimal point Floating Point Numbers are decimals with a variable number of digits before and after the decimal point Javascript stores all numbers as Floating Point Numbers
4
Limitations of Floating Point Numbers
All data on computers are stored in binary format. Binary format cannot store many decimal numbers accurately. Instead, it stores an estimate.
5
Decimal vs Binary Decimal numbers are Base-10 numbers.
Base-10 numbers use the digits 0 through 9 and the number places 1s, 10s, 100s... Binary numbers are Base-2 numbers. Base-2 numbers use the digits through 1 and the number places 1s, 2s, 4s, 8s, 16s... A detailed lesson about converting between decimal and binary numbers is available at “Decimal Number” here refers to the number’s base, not to a number that contains a decimal point Again, all data on computers is stored in binary format
6
Decimal vs Binary Simple decimal point numbers that we use everyday do not convert accurately from Base-10 to Base-2. Base-10 Closest estimate Base-2 can store 0.1 becomes 0.2 0.3 0.4 0.6 Integers convert accurately between base 10 and base 2 But fractions (numbers with decimal points) do not Skipped 0.5 because it is actually stored accurately That’s because 0.5 is one half, and Base-2 numbers are good at stored halves Notice that some estimates are higher than the original number, and some are lower
7
What does this mean for Javascript?
Integers can be accurately stored from -253 through +253. That’s through (about 9 quadrillion). Theses values are accessible with Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER. Outside of that range, you will see errors: Number.MAX_SAFE_INTEGER + 1 == Number.MAX_SAFE_INTEGER + 2 This is range because the floating point number has an Exponent of zero, leaving the Sign to be positive or negative and the Significand with 52 bits. How do we get a range based on 53 bits from a 52 bit memory space? There is an assumed extra bit 1 at the beginning of the Significand that Standard IEEE-754 uses to squeeze a little more data into a small space.
8
What does this mean for Javascript?
When you start using non-integer numbers (decimal point numbers), you lose that accuracy. Accurate decimal point math cannot be performed in Javascript. There are many Javascript libraries that use various work-arounds to avoid this problem. The more important accuracy is to your application, the more carefully you will need to test the libraries you use. It is recommended that financial and scientific operations not be performed in Javascript. Instead, run these operations in a language with native support for the appropriate number data types.
9
Most Common Work-around: Ignore It
var amountA = 0.1; var amountB = 0.2; var total = amountA + amountB; total: console.log(total.toFixed(2)); output: “0.30” That works well enough for displaying a number, but it does not work when comparing numbers. var x = ; console.log(x); output: console.log(x == 0.1); output: false Most common work-around is to ignore the problem Do the math like normal, and use toFixed(2) to display the result toFixed(decimalPoints) returns a string with the number rounded to the specified decimal places Don’t try to convert that string back to a number, it will simply revert to the previous best-estimate value. That’s the same reason Math.round only returns integers - if it tried to round to a specified number of decimal places, it would end up at the same problem that it just cannot store that number and must return an estimate. And Math.round(x) only returns integers, so you can’t even use that.
10
Floating Point Numbers: Standard IEEE-754
Floating point numbers are stored using 64 bits of memory. This space is divided into the Sign, Exponent, and Significand. Sign: 1 bit Exponent: 11 bits Significand: 52 bits When converted into Base-10 Scientific Notation, this is written Sign x Significand x 10 Exponent Going into how floating point numbers are physically stored This is the double-precision floating point number standard because that is the one Javascript uses
11
Scientific Notation Normalized Scientific Notation
= x 100 = x 101 = x 102 = x 103 = x 100 = x 10-1 = x 10-2 = x 10-3 Normalized Scientific Notation There is exactly one digit to the left of the decimal point, and it cannot be a zero. = x 102 Exponential Notation There are many ways to write the same number in Scientific Notation There is one way to write the same number in Normalized Scientfic Notation Because superscripts are hard to display in a console, computers usually display in Exponential Notation. Javascript always displays very large and very small numbers in Normalized Exponential Notation. So the Significand is our significant digits ( ) And the Exponent (2) sets how large or small the number is Negative exponents make small numbers and positive exponents make large numbers = e+2
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.