Get into the habit of writing together! This is the 19th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .
Calculating the sum of two decimal numbers in JavaScript sometimes produces surprising results, I believe everyone knows this!
loss of precision
For example, the result we 0.1 + 0.1
get in the calculation is 0.2
, but 0.1 + 0.2
the result of the calculation is not 0.3
, but 0.30000000000000004
This phenomenon not only occurs in addition, but also in subtraction with similar results.
For example 1.2 - 1
the result is 0.19999999999999996
This is not unique to JavaScript though, other programming languages have the same problem.
For example output in the Python environment.
print(.1 + .2)
复制代码
The result obtained is also: 0.30000000000000004
reason
The main reason for this problem is that computers store data as binary .
How to convert integer from decimal to binary
A decimal integer can be converted to binary by dividing it by 2. Take the quotient and keep dividing by 2 until it reaches zero.
Every time you perform this division, note the remainder . Now reverse the remainder list to get the number in binary form.
For example, I want to convert 29 to binary:
29÷2=14 excess1
14÷2=7 excess0
7÷2=3 excess1
3÷2=1 surplus1
1÷2=more than 01
The binary number representing decimal 29 is 11101
.
E.g:
-
1 is 1
-
10 is 1010
Convert decimal from decimal to binary
Decimal decimals are converted into binary decimals using the "multiply 2 rounding, orderly arrangement" method. The specific method is: multiply the decimal fraction by 2 to obtain the product, take out the integer part of the product, then multiply the remaining fractional part by 2 to obtain a product, and then take out the integer part of the product, and so on, until the The fractional part is zero, and 0 or 1 is the last digit in binary. or until the required accuracy is achieved.
For example: I want to convert 0.375 to binary:
0.375*2=0.75 get 0
0.75*2=1.5 gets 1
0.5*2=1 gets 1, the decimal is gone, and the end. The final conversion to binary is 0.011
E.g:
- 0.1 is 0.0001100110011001100110011001100110011001100110011001101
- 0.2 is 0.001100110011001100110011001100110011001100110011001101
Not every decimal number can be represented perfectly in this binary format, as some numbers may be converted to
When JavaScript is calculating, it will first convert the decimal to binary and perform the calculation.
0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111
复制代码
The result obtained here is 0.0100110011001100110011001100110011001100110011001100111
converted to decimal and is 0.300000000000000004
solution
third party library
Decimal
x = new Decimal(0.1)
y = x.plus(0.2)
复制代码
bignumber
x = new BigNumber(0.1)
y = x.plus(0.2)
复制代码
become an integer
The main idea is: first convert the decimal to split two strings, then calculate the length of the string of the fractional part, and then use this length to turn the decimal into an integer!
function add(num1, num2) {
const num1Len = (num1.toString().split('.')[1] ).length;
const num2Len = (num2.toString().split('.')[1] ).length;
const maxLen = Math.pow(10, Math.max(num1Len, num2Len));
return (num1 * maxLen + num2 * maxLen) / maxLen;
}
复制代码