Comparing floats in JavaScript produce unexpected results [duplicate] - javascript

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 years ago.
This kind of blows my mind..
http://pastebin.com/Q3MtpPpM
Turns out the output is "surprise!!". Doesn't this sort of undermine using JavaScript in some way if a program was going to use lots of floating point values?

One way of comparing floats could be by converting them to String values using toFixed() method
var fl1 = 0.11;
var fl2 = 0.11;
if ( fl1.toFixed(10) == fl2.toFixed(10) )
{
//same value
}

Javascript numbers are 64 bit floating point. see this ECMAScript specification.
http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19
Floating point arithmetic in any programming language is prone to errors and is not always guaranteed to be accurate. see following for more on Floating point airthmatic
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
for more see the following QA
Is floating point math broken?
And yes its a WAT, but following rules can help you avoid errors
dont do equality checks
in case of critical floats where you know maximum points after denomination for example currency store multiplied value by that base.
for currency store in cents instead of dollors.
54.67 as 5467 --- and divide by 100 before display.
For more read following post (its for c++ but will give insights on floating point erros)
http://www.codeproject.com/Articles/29637/Five-Tips-for-Floating-Point-Programming

Related

Why JavaScript return me a wrong result in this subtraction of decimals values? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 7 years ago.
I am pretty new in JavaScript and I have found a very strange situation doing an extremely simple mathematical operation: a subtraction.
So in a jQuery function I have this code:
saldoRicalcolato = finanziamento - variazioneAnticipoNumber;
Where finanziamento and variazioneAnticipoNumber are 2 numbers having decimal digits.
It works almost always good except for some specific values.
You can replicate the strange behavior performing this statement into the FireBug console:
2205.88 - 1103.01
1102.8700000000001
So in this case the result is substantially wrong because I obtain 1102.8700000000001 and not 1102.87 as I expected.
Why? What am I missing? Is it a JavaScript engine bug or something like this? Possible?
It's not a JavaScript problem but a more general computer problem. Floating number can't store all decimal numbers properly, because they store stuff in binary For example:
0.5 is store as b0.1
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc
so in binary 0.1 is 0.00011...
but that's endless. Except the computer has to stop at some point. So if in our example we stop at 0.00011 we have 0.09375 instead of 0.1.
It doesn't depend on which language but on the computer, what depends on the language is how you display the numbers. Usually the language will round numbers to an acceptable representation but apparently JavaScript doesn't.
If you're looking to get 1102.87. You'll need to set the decimal place to 2 by using toFixed()
This is just a solution of getting the number you want.
alert((2205.88 - 1103.01).toFixed(2));

String to number is wrong [duplicate]

This question already has answers here:
Large numbers erroneously rounded in JavaScript
(6 answers)
Javascript parseInt() with leading zeros
(7 answers)
Closed 7 years ago.
I'm trying to convert a string to number in Javascript, but here is my problem :
var string = "068999999501111443";
parseInt(string); // 68999999501111440
Number(string); // 68999999501111440
Why does this happen and how to fix it ?
Thanks
This is because the number is too large to be stored accurately. It is being stored as a floating point number, which can only store a certain amount of precision. Beyond it's maximum precision, you'll get what look like weird rounding errors.
You'll get similar effects for decimals with a large number of decimal places. This is more well known, as it tends to occur more often, but it's exactly the same effect that is happening here.

A lot of decimals in javascript operations [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
I'm running the following javascript code:
var var1 = 0.53;
var var2 = 0.47;
alert(var1-var2);
This code return:
0.06000000000000005
But if I execute this javascript code:
var var1 = 0.14;
var var2 = 100;
alert(var1*var2);
The return is:
14.0600000000000002
What documentation to explain this?
Thanks!
This is a very fundamental problem that is related to the way floating point numbers are represented (see the wikipedia article for a detailed explanation). It is not specific to javascript.
Since a computer works only on binary values it is not possible to exactly represent certain fractions. Example: 1/2 or 3/4 can be exactly represented. 1/3 on the other hand cannot (like in the decimal system). It is counterintutive that a seemingly "simple" number like 0.14 leads to a rounding error, however, when you think about it as 7/50 = 7/(5 * 5 * 2) it becomes clear. The problem are the fives. 1/5 = 0.2 is nice in the decimal system but not as a binary number.
Update:
I don't mean to say it is not possible to do such kinds of calculations exactly. However, you will have to use certain libraries for this purpose (e.g. for working with currency values)

Javascript negative float number calculation [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is JavaScript’s Floating-Point Math Broken?
In Javascript, how do I compute the result of 23668-23671.88 to -3.88 instead of -3.8800000000010186 ?
I don't want any rounding, since if I use a windows calc, the result is -3.88.
Is it possible?
If you don't want to round, then you need some way of determining the precision of the variables in your expression and apply that precision to the result of the expression. Unfortunately, JavaScript does not have a way to determine the precision of floats.
However, there is a simple 'hacky' way you can accomplish this:
http://jsfiddle.net/SjxCY/2/
var num = 2.383;
var precision = (num+'').split('.')[1].length;
var final = (234234-num).toFixed(precision);
alert(final);
It's not pretty, but it works.
If you don't want a rounding kludge, you cannot use floating point numbers and have to find a decimal arithmetic library. Nothing built-in, I am afraid.

Javascript rounding issue [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 11 months ago.
I've got a weird maths/rounding problem in Javascript.
The snippet below is a very basic example of the code I'm running. Obviously it's not this exact code, but I'm taking a decimal value from a text box, working out a percentage and taking this away from one.
var ten = "10";
var eight = "8";
alert(1 - (eight/ten));
The problem is the answer is 0.2 but the calculation returns 0.1999999999999996. Yet if I do 1 + (eight/ten) 1.8 is returned. What is going on?
Welcome to the world of floating-point numbers!
Computers don't actually work with decimal numbers--i.e. numbers in base ten, the way we use them in normal life. They work with binary numbers, and that includes floating-point numbers. They're represented in binary as well, and that means that "number of decimal places" is not always a meaningful property of a floating-point number.
For instance, a floating-point number cannot exactly represent 0.1, and you'll get something like 0.1000000001 if you try to use it in your code. The exact value you get varies by implementation, and is not correctable by subtracting the difference, as the computer can't tell that there is a difference--that's as close as it can get to 0.1.
(Stole most of this answer from a previous answer of mine.)
It's because of the way floating point numbers are represented.
I have the same result on my android device which means your device or computer works with 64 bits floating point representation. For correct result, you must limit displaying your result to 15 digits. I found this workaround : running :
var res = 1 - 0.8;
var roundedRes = parseFloat(res.toPrecision(15) ) ;
alert ("res="+res+"\n" + "roundedRes="+roundedRes);
ouputs :
res=0.19999999999999996
roundedRes=0.2
JavaScript use binary floating point for representation of numbers like 1/2,1/8...1/1024. But decimal fractions which we mostly use are represented in form 1/10,1/100...
This will not be a problem with JavaScript only but with all languages that use binary floating point representation.

Categories

Resources