0.1+0.2 === 0.3?

Purpose: To understand the problem described by the title

  1. Answer: Not equal.
  2. IEEE 754 can only represent 1/2, 1/4, not 1/10

The binary storage of 0.1 and 0.2 in the computer will cause them to lose a certain degree of accuracy, and their binary storage in the computer is no longer the real 0.1 and 0.2 when converted to decimal, and the result of the addition is naturally not 0.3.

How to convert 0.1 to binary

0.1*2 = 0.2 takes the integer 0
0.2*2 = 0.4 takes the integer 0
0.4*2 = 0.8 takes the integer 0
0.8*2 = 1.6 takes the integer 1
0.6*2 = 1.2 takes the integer 1
, etc.

5.5 How to convert to binary

5.5 Convert to Binary =====> 101.1 Scientific Notation =====> 1.011*2^2
Save to computer:
Sign bit: 0
Exponent bit: 2 plus 1023 =====> 1025 Convert to binary === ==> 10000000001
mantissa digit: 1.011 conceal the 1 to the left of the decimal point =====> 011

How to resolve floating point errors

1. Judgment

It is impossible to deal with infinite decimals in a limited space, so for judgments, use toPrecision+parseFloat

// 一般精度12就够了
function strip(num, precision = 12) {
  return +parseFloat(num.toPrecision(precision));
}

2. Operation

  1. Take precision (use toFixed to solve (note: 1.005.toFixed(2) === 1.00, not 1.01)
  2. Add strings.
  3. The third party library uses bignumber. js solves, but the performance is slightly worse.

Why let a = 0.1, a is equal to 0.1

If an IEEE 754 double-precision floating-point number is converted into a decimal number string containing at least 17 significant digits, when the string is converted back to a double-precision floating-point number, it must be the same as the original number; in other words, if a When a double-precision floating-point number is converted to a decimal number, as long as the double-precision floating-point number it returns does not change, the shortest precision will do.

Take 0.1 as an example. The storage of 0.1 and 0.10000000000000001 converted into double-precision floating-point numbers is the same, so the shortest 0.1 will do.

The Number.prototype.toPrecision()
toPrecision() method returns the string representation of the numeric object with the specified precision.

Number(100).toString(2) —> '1100100' Decimal conversion
var num = 1100100;
console.log(parseInt(num,2));

How to store iEEE 754 floating point numbers

  1. Double-precision storage, 1 sign bit + 11 exponent bits + 52 mantissa bits
  2. Maximum and minimum values.
  3. Safe maximum and safe minimum.
  4. Conversion formula

note

Why 1.005.toFixed(2)=1.00 instead of 1.01

1.005.toPrecision(6) = == 1.00499

//通过isEqual工具方法判断数值是否相等
function isEqual(number1, number2, digits){
    
    
  digits = digits == undefined? 10: digits; // 默认精度为10
  return number1.toFixed(digits) === number2.toFixed(digits);
}
console.log(isEqual(1.0-0.7, 0.3));  //true
//原型扩展方式,更喜欢面向对象的风格
Number.prototype.isEqual = function(number, digits){
    
    
  digits = digits == undefined? 10: digits; // 默认精度为10
  return this.toFixed(digits) === number.toFixed(digits);
}
console.log((1.0-0.7).isEqual(0.3)); //true

What is the meaning of Number.MAX_VALUE and Number.MAX_SAFE_INTEGER?

Safe integers will not be distorted.

to sum up

For floating-point numbers, these can basically solve the problems encountered in general.

Citing articles

Talking about the principle of JavaScript floating-point number and its arithmetic
floating-point number demo website
front-end should know JavaScript floating-point number and large number

Guess you like

Origin blog.csdn.net/a519991963/article/details/114634338