web123456

js negative numbers compare size_JS the embarrassment of the calculation of imprecise problems

Click on the blue letters above to follow us

Editor's Note: The translation is provided by Alibaba's Corporate Finance Division - Virtual Trace students, it is recommended to collect and read, a better understanding of the js computing imprecision of the text of the same Oh!

existjavascriptInternally, there is only one type of number, which follows the IEEE-754 specification for double precision.floating pointIt is stored in binary format and occupies 64-bit storage space.

  • Sign Bit S: Bit 1 is the sign bit for positive and negative numbers, with 0 representing a positive number and 1 representing a negative number.

  • Exponent Bit E: The middle 11 bits store the exponent, which is used to represent the sub-particle number

  • M: the last 52 digits are the mantissa, and any excess is automatically rounded up to zero.

If a number is too large for 64-bit storage, it can lead to infinity:

alert( 1e500 ); // Infinity

This example may not be encountered often, and is more commonly known as a loss of precision.

Consider the following example:

alert( 0.1 + 0.2 == 0.3 ); // false

If we check0.1 cap (a poem)0.2 Is the sum of the0.3We're gonna getfalse

Strange! If it wasn't.0.3What could that be?

alert( 0.1 + 0.2 ); // 0.30000000000000004

Ouch! This error is unthinkable. Imagine you placed an order at a shopping site¥ 0.10 cap (a poem)¥ 0.20 of items to the shopping cart. The order total will be¥ 0.30000000000000004. You might be shocked by such an order total.

Why is that?

A number is stored in memory in binary form as a sequence of only 1s and 0s. As simple as it may seem in the decimal number system, the0.10.2 Such decimals are, in fact, infinitely cyclic decimals in binary form.

In other words, what is0.10.1 just like1 divided by101/10, i.e., one-tenth. It is easy to represent such a number in the decimal numbering system. Compare it to one-third:1/3. One-third becomes an infinite loop decimal0.33333(3)

In a decimal numbering system, it is guaranteed to start with a10 integer powers as divisors work fine, but the3 As a divisor it cannot. It is also for the same reason that in the binary number system it is guaranteed that the number in the form of a2 works fine when the integer powers of the1/10 It becomes an infinite loop of binary decimals.

The use of the binary number system does notprecisely stockpile0.1 maybe0.2, just as there is no way to store a third as a decimal decimal.

IEEEThe -754 number format solves this problem by rounding numbers to the nearest possible number. These rounding rules don't usually allow us to see a "minimal loss of precision", but it does exist.

We can see:

alert( 0.1.toFixed(20) ); // 0.10000000000000000555

When we sum two numbers, their "loss of precision" is superimposed.

That's why.0.1 + 0.2 not equal ≠0.3

Can we solve this problem? Of course, the most reliable way is to round the result with the help of the method toFixed(n):

let sum = 0.1 + 0.2;alert( sum.toFixed(2) ); // 0.30

Please note.toFixed Always returns a string. It ensures that there are 2 digits after the decimal point. If we have an online shopping site and we need to display the¥ 0.30, which is actually quite convenient. For other cases, we can use the one-dollar plus sign to force it to convert to a number:

let sum = 0.1 + 0.2;alert( +sum.toFixed(2) ); // 0.3

We can temporarily multiply a number by 100 (or a larger number), convert it to an integer, perform the math operation, and then divide back. When we use integers for math operations, the error is reduced, but you can still get it in division:

alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001

Thus, multiplication/division reduces the error, but does not eliminate it completely.

In fact, the industry has a relatively mature component library can solve this problem, here to give you the recommended

0.1 + 0.2                       // 0.30000000000000004x = new BigNumber(0.1)y = x.plus(0.2)                 // '0.3'BigNumber(0.7).plus(x).plus(y)  // '1'x.plus('0.1', 8)                // '0.225'

This article was translated to

/number

put at the end

Square Stool Yaji is a public number maintained by Alibaba's B-series 6 BUs (1688, ICBU, Retail, AE, Enterprise Finance, and Koala), we will send out good quality articles on a regular basis, welcome to scan the code and pay attention!

demand attention

request a retweet