- Why 0.1 + 0.2! = = 0.3?
- Why is number. MAX_SAFE_INTEGER math.pow (2, 53) -1?
- Why does Math.pow(2, 53) === math.pow (2, 53) + 1?
- Why Number.MAX_VALUE = 1.7976931348623157e+308?
- Why 1.005.toFixed(2) = 1.00?
1. Floating point binary storage structure
The following figure shows the single-precision format
Why E(double) range: -1022 to 1023?
// Range E = 0 0 1111 1111 1111 => 2^ 10-1 = 1023 E Maximum binary representation: 1 1111 1111 10 => 2^ 11-2 = 2046 E Minimum binary representation (cannot all be 0): 0000 0000 0000 0000 0000 0000 0000 0000 00Copy the code
2. Any number can be expressed as binary:1.xxx * 2^e
(This is a normalized representation),
Decimal floating point number to binary, eg:
0.125 x 2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | 0 0.25 x 2 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | 0 0.5 x 2 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | 1.0 1 leftCopy the code
13.125, integer part 13 => 1101, decimal part 0.125 => 0.001
13.125 => 1101.001 => 1.101001 * 2^3(the 1 before the decimal point is omitted to save space) // S=0; E=3(binary :10000000010); M = 101001, binary representation as: 0 10000000010 1010010000000000000000... -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (1023 + 3), M, s E 52 lengthCopy the code
0.1 Conversion bit binary: 0.0001100110011(0011 loop) => 1.100110011(0011)*2^-4 0.2 conversion bit binary: 0.0001100110011(0011 loop) => 1.100110011(0011)*2^-4 0.001100110011(0011 cycle) => 1.100110011(0011)*2^-3
3. The operation
- Alignment of small and large order codes 0.1:1.100110011 (0011)*2^ -4 = 0.1100110011(0011) *2^-3 0.2:1.100110011 (0011)*2^-3
- Mantissa rounded near:
A. Redundant bits <= 011… 11, abandoned. [b]. [C]. 00, judge the value of the least significant digit of the mantissa. If it is 0, it will be directly eliminated; if it is 1, it will be added by 1. C. Redundant bits >= 100… 01, enter 1.
0.1 = > 0.1100110011001100110011001100110011001100110011001100 [1100110011]... = > into 0.1100110011001100110011001100110011001100110011001101 0.2 = 1 = > > 1.1001100110011001100110011001100110011001100110011001 [100110011]... = > into 1 = > 0.1100110011001100110011001100110011001100110011001110 0.1100110011001100110011001100110011001100110011001101 * + 1.1100110011001100110011001100110011001100110011001110 * 2 ^ ^ 2-3-3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10.0110011001100110011001100110011001100110011001100111 * ^ 2-3 = > 1.00110011001100110011001100110011001100110011001100111 * 2 ^ 2 = > 1.0011001100110011001100110011001100110011001100110100 * 2 ^ 2 (because the mantissa can only 52, Converted to decimal rounding to the nearest) = 0.3000000000000000444089209850062616169452667236328125 > 0.30000000000000004Copy the code
4. To reassure
- Why 0.1 + 0.2! = = 0.3? A. Figure out the storage structure of number; B. Know the conversion between decimal binary; C. Understand the calculation process.
- Why is number. MAX_SAFE_INTEGER math.pow (2, 53) -1? Because binary represents: 1. XXX * 2^e, the mantras of XXX are at most 52 bits, then e<=52 is accurate, and there is a precision loss beyond that, then the binary 53 ones are equal to Math.pow(2, 53) -1.
- Why does Math.pow(2, 53) === math.pow (2, 53) + 1? Because 1(decimal) => 1 * 2^0(binary) => 0.000… 1 * 2^53(mantissa 52 0, 1, rounded nearest) === 0
- (2^53, 2^54) will be one of the two numbers, and it can only be an even number
- The number between (2^54, 2^55) will be one of four, and can only represent four multiples exactly
- . Skip more multiples of 2 in turn
Math.pow(2, 53) + 3 === Math.pow(2, 53) + 5 // true
Math.pow(2, 54) === Math.pow(2, 54) + 1 // true
Math.pow(2, 54) === Math.pow(2, 54) + 2 // true
Copy the code
- Why Number.MAX_VALUE = 1.7976931348623157e+308? The maximum integer is math.pow (2, 1024) -1, but 2^1024 is Infinity.
Math.pow(2, 1024) // Infinity math.pow (2, 1023) * 1.999999999999999 // 1.797693134862315e+308Copy the code
- Why 1.005.toFixed(2) = 1.00? Look at the mountain is not a mountain, 1.005 actually corresponding to the number is 1.00499999999999989, in the round off all! The toPrecision function can view the accuracy.
Reference documentation
Coolcao.com/2016/10/12/… Github.com/camsong/blo…