Dart, float for loop will cause strange result


for(int i=0; i<10; i++) {
    priceValue.add(54.99 + i*5);
    print(54.99 + i*5);


js_primitives.dart:30 54.99
js_primitives.dart:30 59.99
js_primitives.dart:30 64.99000000000001
js_primitives.dart:30 69.99000000000001
js_primitives.dart:30 74.99000000000001
js_primitives.dart:30 79.99000000000001
js_primitives.dart:30 84.99000000000001
js_primitives.dart:30 89.99000000000001
js_primitives.dart:30 94.99000000000001
js_primitives.dart:30 99.99000000000001

What causes the 00000000001 to appear?


It’s just how double numbers work. You would get the same result in other languages that use the same doubles as Dart (they are standardized as IEEE-754 64-bit floating point numbers).

The crux is that, e.g., 89.99 cannot be represented exactly by the precision of doubles. Doubles are binary numbers with at most 53 significant bits.
In binary, 89.99 doesn’t have a finite representation, just like 1/3 cannot be written finitely as a decimal number (0.3333333…. it’s never enough for the precise value).

There are only a finite number of double values, spread throughout the range that doubles cover. So, when you try to convert a “real” number to a double, the computer rounds to the closest double value to the original number.

Even 54.99 isn’t precise. The actual double value of 54.99 is the double closest to the mathematical number 54.99 (aka 5499/100):


Then you add 35 to that, which again isn’t representable as a double, and the double hardware picks the closest double to that value:


Due to the imprecission on the original 54.99, that is actually a different double than the one that would be picked for just writing 89.99, which is:


When you convert a double to a string, the algorithm for picking a representation is actually clever. It picks the shortest decimal representation where the numerical value will be rounded to the original double value.

So, since 54.99 + 35 is not the same double as 89.99, they need to have different string representations. The string 89.99 is obviously taken for the latter, so 54.99 + 35 needs more digits to distinguish itself. That’s where the trailing 00000000000001 comes from.

So, in short, it’s just what doubles do. The same computation will give the same result in most other languages that use the same double type.

Answered By – lrn

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *