Javascript Math Error: Inaccurate Floats

Possible duplicates:
Is javascript and math broken?
How is a floating point stored? When does it matter?

the code:

var tax= 14900*(0.108); alert(tax); 

The above answer gives the answer 1609.2

 var tax1= 14900*(10.8/100); alert(tax1); 

The above answer gives the answer 1609.200000000003

why? I think I can round values, but why is this happening?

UPDATE: Found a workaround.

Multiply first:

 (14900*10.8)/100 = 1609.2 

However

 (14898*10.8)/100 = 1608.9840000000002 

To do this, multiply 10.8 by a factor(100 in this case) and adjust the denominator:

 (14898*(10.8*100))/10000 = 1608.984 

I assume that if you can preg_match for an extra 000 and then adjust the coefficient accordingly, you can avoid a float error. The final solution, however, would be a math library .

+4
source share
4 answers

Floating point value is inaccurate.

This is largely the answer to the question. There is ultimate accuracy, which means that some numbers cannot be represented accurately.

Some languages ​​support arbitrary precision numeric types / rational / complex numbers at the language level, etc., but not Javascript. Neither C nor Java.

The standard value of the floating point IEEE 754 cannot represent, for example. 0.1 sure. That is why numerical calculations with cents, etc. Must be performed very carefully. Sometimes the solution is to store the values ​​in cents as integers, and not in dollars, like floating point values.


The concept of a "floating" point, analogue in base 10

To understand why floating point values ​​are inaccurate, consider the following counterpart:

  • You have enough memory to store 5 digits
  • You want to be able to represent values ​​in a wide range as practical as possible.

When representing integers, you can represent values ​​in the range from -99999 to +99999 . Values ​​outside this range will require you to remember more than 5 digits that (for this example) you cannot do.

Now you can consider a fixed-point view, something like abc.de Now you can represent values ​​in the range from -999.99 to +999.99 , up to two digits of accuracy, for example. 3.14 , -456.78 , etc.

Now consider the floating point version. In your resourcefulness, you have come to the following scheme:

n = abc x 10 de

Now you can only remember 5 digits a , b , c , d , e , but now you can imagine a much wider range of numbers, even non-integer ones. For instance:

123 x 10 0 = 123.0

123 x 10 3 = 123,000.0

123 x 10 6 = 123,000,000.0

123 x 10 -3 = 0.123

123 x 10 -6 = 0.000123

This is how the name "floating point" appeared: the decimal point "floats around" in the above examples.

Now you can imagine a wide range of numbers, but note that you cannot imagine 0.1234 . You also cannot submit 123,001.0 . In fact, there are many meanings that you cannot imagine.

This is pretty much why floating point values ​​are inaccurate. They can represent a wide range of values, but since you are limited by a fixed amount of memory, you must sacrifice accuracy in magnitude.


Additional specifications

abc is called significant , the so-called coefficient / mantissa. de is an exponent as a scale / characteristic. As usual, base 2 is used instead. 10. In addition to remembering “numbers” (a bit, really), it should also remember signs of significance and indicator.

A single-precision floating-point type typically uses 32 bits. Double precision typically uses 64 bits.

see also

+17
source

This behavior is inherent in floating point arithmetic. This is why floating point arithmetic is not suitable for solving money problems that need to be accurate.

There are libraries such as this one that help you limit rounding errors to the point where you need them (present as text). These libraries do not deal with floating point values, but with fractions (integer values). So there is no 0.25, but 1/4, etc.

+3
source

Floating-point values ​​can be used to efficiently represent values ​​in a much wider range than integer values ​​can be. However, this happens at a price: some values ​​cannot be represented exactly (since they are stored binary). Each negative power is 10, for example (0.1, 0.01, etc.)

If you want accurate results, try not to use floating point arithmetic.

Of course, sometimes you cannot avoid them. In this case, a few simple guidelines will help you minimize rounding errors:

  • Do not subtract almost equal values. (0.1-0.0999)
  • First add or multiply the largest values. (100 * 10) * 0.1 instead of 100 * (10 * 0.1)
  • Multiply first, then divide. (14900 * 10.8) / 100 instead of 14900 * (10.8 / 100)
  • If exact values ​​are available, use them instead of calculating them to get a more beautiful code.
+2
source

Moreover,

for JavaScript to calculate the mathematical advantage, there is no reason to use parentheses:

 var tax1 = 14900 * 10.8 / 100 1609.2 

This is magic. Just remember to avoid useless parentheses.

-3
source

All Articles