double accuracy in C++

Started by
5 comments, last by Anthony Serrano 5 years, 7 months ago

a simple assignment such as bellow 


    int main()
    {
         double variable = 1.4;
         double value = variable;
         return 0;
    }

the value of both variable and value is 1.399999999999999

Why is this?

BUT when setting this

    double value = 1.5;

Gives correct result!! why?

Any idea on how to resolve this or atleast a workaround?

image.png.8fc4fe671631807f7b68bf156eacb810.png

Advertisement

There is infinite real numbers, while double can only present finite numbers, so it can't present all numbers.

To solve it, you need fixed point number

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

You can get a thorough answer in the classic 1991 paper "What every computer scientist should know about floating-point arithmetic".

If you want just a quick answer to why 1.4 is not an exact double but 1.5 is, the key is that doubles are internally represented in base 2. 1.5 is actually "1.1" in base 2, but 1.4 is "1.011001100110011001100110011001100110011001100110011001100110011001...". Since the binary expansion of 1.4 is infinite and a double keeps only 53 significant bits, some rounding will happen, and in this case that makes the number a bit less than 1.4.

So what you are observing is similar to what happens if you write 1/3 to 8 decimal digits. You'll get 0.33333333, which is a bit less than 1/3.

 

 

3 hours ago, cebugdev said:

 

Any idea on how to resolve this or atleast a workaround?

 

As others have noted this is a function of the fact that certain real numbers can not be represented in binary with an exact representation the same as they can in decimal. However in most cases this isn't so critical. For instance if you were to print out 1.4 using printf("%3.1f",1.4) , it will generally give you what you want (i.e. 1.4) even though the internal representation is closer to 1.399999999999999 . Basically your problem is with formatting. So your GUI needs to have some option to do the appropriate formatting on output. Baring that, you can use sprintf or the C++ stream equivalent to format your number and convert it to a string before handing it to your GUI. 

If you really need to store 1.4 exactly you would probably have to use something like BCD. Binary Coded Decimal .  As I recall old 16 bit intel CPUs had some machine language opcodes to help support BCD but I'm not sure if it was carried forward in later architectures. I'm guessing that's not what you really need anyway.

Just to add that, this is not unique to C++. Anything that uses (binary) floating point decimal will display this kind of problem. In fact, this is by-design. 

 

http://9tawan.net/en/

It's not even a matter of design, it's an inherent property of representing fractions with a finite number of digits. A rational non-integer number can only be accurately represented with a finite number of digits if all the prime factors of the denominator are also prime factors of the radix; otherwise, it requires an infinitely repeating digit sequence.

 

This topic is closed to new replies.

Advertisement