Waseem
Waseem

Reputation: 33

C++ internal representation of double/float

I am unable to understand why C++ division behaves the way it does. I have a simple program which divides 1 by 10 (using VS 2003)

double dResult = 0.0;
dResult = 1.0/10.0;

I expect dResult to be 0.1, However i get 0.10000000000000001

  1. Why do i get this value, whats the problem with internal representation of double/float
  2. How can i get the correct value?

Thanks.

Upvotes: 1

Views: 4742

Answers (4)

Kemin Zhou
Kemin Zhou

Reputation: 6891

Working with integers, floats, and doubles could be tricky. Depends on what is your purpose. If you only want to display in nice format, then you can play with the C++ iomanipulator, precision, showpint, noshowpint. If you are trying to do precise computing with numeric methods, you may have to use some library for accurate representation. If you are multiplying a lots of small and large number, you may have to resole to use log transformations. Here is a small test:

  float x=1.0000001;
   cout << x << endl;
   float y=9.9999999999999;
   cout << "using default io format " << y/x << endl;
   cout << showpoint << "using showpoint " << y/x << endl;
   y=9.9999;
   cout <<  "fewer 9 default C++ " << y/x << endl;
   cout << showpoint << "fewer 9 showpoint" << y/x << endl;

1
using default io format 10
using showpoint 10.0000
fewer 9 default C++ 9.99990
fewer 9 showpoint9.99990

In special cases you want to use double (which may be the result of some complicated algorithm) to represent integer numbers, you have to figure out the proper conversion method. Once I had a situation where I want to use a single double value to store two type of values: -1, +1, or (0-1) to make my code more memory efficient (and speed, large memory tends to reduce performance). It is a little tricky to distinguish between +1 and val < 1. In this case I know that the values < 1 has a resolution say only 1/500, Then I can safely use floor(val+0.000001) to get back the 1 value that I initially stored.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272657

Because all most modern processors use binary floating-point, which cannot exactly represent 0.1 (there is no way to represent 0.1 as m * 2^e with integer m and e).

If you want to see the "correct value", you can print it out with e.g.:

printf("%.1f\n", dResult);

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477368

The ubiquitous IEEE754 floating point format expresses floating point numbers in scientific notation base 2, with a finite mantissa. Since a fraction like 1/5 (and hence 1/10) does not have a presentation with finitely many digits in binary scientific notation, you cannot represent the value 0.1 exactly. More generally, the only values that can be represented exactly are those that fit precisely into binary scientific notation with a mantissa of a few (e.g. 24 or 53 or 64) binary digits, and a suitably small exponent.

Upvotes: 2

amit
amit

Reputation: 178481

Double and float are not identical to real numbers, it is because there are infinite values for real numbers, but only finite number of bits to represent them in double/float.

You can further read: what every computer scientist should know about floating point arithmetics

Upvotes: 2

Related Questions