C ++ How to avoid a floating point arithmetic error

I am writing a loop that increments with float, but I ran into the floating point arithmetic problem illustrated in the following example:

for(float value = -2.0; value <= 2.0; value += 0.2) std::cout << value << std::endl; 

Here is the result:

 -2 -1.8 -1.6 -1.4 -1.2 -1 -0.8 -0.6 -0.4 -0.2 1.46031e-07 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 

Why exactly do I get 1.46031e-07 instead of 0 ? I know that this has something to do with floating point errors, but I cannot understand why this is happening, and what I have to do to prevent this from happening (if there is a way). Can someone explain (or point me a link) to help me understand? Any input is appreciated. Thank you

+6
source share
6 answers

This is because floating point numbers have only a certain discrete precision.

0.2 is actually not 0.2, but internally represented as a slightly different number.

That is why you see the difference.

This is common in all floating point calculations, and you really cannot avoid it.

+7
source

Like everyone else, this is done so that real numbers are infinite and uncountable, while floating point representations use a finite number of bits. Floating-point numbers can approximate real numbers and even in many simple cases are not exact due to their definition. As you now notice, 0.2 is actually not 0.2 , but rather a number very close to it. When you add them to value , you accumulate an error at every step.

Alternatively, try using int for your iteration and split the result to return it to the desired domain:

 for (int value = -20; value <= 20; value += 2) { std::cout << (value / 10.f) << std::endl; } 

For me it gives:

 -2 -1.8 -1.6 -1.4 -1.2 -1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2 
+23
source

There is no clear solution to avoid loss of floating point precision. I would suggest looking at the following document: What Every Computer Scientist Should Know About Floating-Point Arithmetic .

+6
source

Use integers and divide down:

 for(int value = -20; value <= 20; value += 2) std::cout << (value/10.0) << std::endl; 
+5
source

Let your cycle, but with increased output accuracy.

code:

 for(float value = -2.0; value <= 2.0; value += 0.2) std::cout << std::setprecision(100) << value << std::endl; 

output:

 -2 -1.7999999523162841796875 -1.599999904632568359375 -1.3999998569488525390625 -1.19999980926513671875 -0.999999821186065673828125 -0.79999983310699462890625 -0.599999845027923583984375 -0.3999998569488525390625 -0.19999985396862030029296875 1.460313825418779742904007434844970703125e-07 0.20000015199184417724609375 0.400000154972076416015625 0.6000001430511474609375 0.800000131130218505859375 1.00000011920928955078125 1.20000016689300537109375 1.40000021457672119140625 1.60000026226043701171875 1.80000030994415283203125 
+5
source

Learn about floating point representation using some algorithm books or using the Internet. There are many resources.

For a while, it seems to you that you want to get zero when its something is very close to zero. and we all know that we call this process “rounding.” :) So why don't you use it when printing these numbers. The printf function provides good formatting power for such things. check the tables in the following link if you don't know how to format with printf. (you can use formatting to round and display numbers correctly) printf ref: http://www.cplusplus.com/reference/cstdio/printf/?kw=printf

- change -

Perhaps some of you know that according to math 1.99999999 .... this is the same as 2.0. The only difference is the presentation. But the number is the same.

floating point problem is a bit similar to this. (this is for your clarification only). Your problem does not coincide with 1.9999 .... thing.)

+1
source

All Articles