This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Floats different printing than doubles?



Christopher Denney <chris@isis.bbmbc.org> writes:

> I wrote a simple cash register program (c++) that was supposed to print the
> input number multiplied by 1.03 rounded to two decimal places.
> 
> I failed to get the correct output when the type was double, but it works
> fine when the type is float. It seems to have difficulty with rounding .055
> to .06, but it will round .056 to .06. Float works fine in all cases I
> tested.
> 
> I am running gcc-2.95.2 on a sun sparc with solaris 2.5.1, no extra config
> flags.
> -------------------------------------------------------------
> //    cash.cpp
> #include <iostream>
> 
> int main()
> {
>         float val1;             // Input Value
>         float res;              // Result
> 
>         cout << "\nCash Register Running\n";
>         cout << "Please Input Value: ";
>         cin >> val1;
>         res = val1 * 1.03;
>         cout.precision(2);
>         cout.flags(ios::fixed | ios::showpoint);
>         cout << "\nTotal Sale = " << res << "\n\n";
>         cout << "Thank you. Have a nice day.\n" << endl;
> 
>         return 0;
> }
> -------------------------------------------------------------
> 
> compiled with:
> $ c++ cash.cpp
> run with:
> $ a.out
> input of 18.5 gives output of 19.06
> change the float types to double and input of 18.5 gives output of 19.05
> 
> This I thought was wrong. :)

This is caused by rounding.  In binary, 1.03 is
1.00000*11110101110000101000* with the bit between '*'s repeating
forever; you've written plain '1.03', so it gets to be a double, which
makes it: 1.00000111101011100001010001111010111000010100011110110
Multiply this by 18.5 (which is exactly representable in binary), you
get 10011.00001110000101000111101011100001010001111010111000111
exactly, then if you round that to 'float' you get
10011.0000111000010100100 which was rounded up; if you round it to
'double' you get
10011.0000111000010100011110101110000101000111101011100 which is
rounded down.  The 'true' answer is 19.55 which is
10011.0000*11100001010001111010*  with the bit between the *s repeating.

So one of these is a little bit below 19.55, so it gets rounded down
to 19.5, the other one a little above so it gets rounded up.
-- 
- Geoffrey Keating <geoffk@cygnus.com>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]