-3

Why doubles round themselves? How can i prevent it? If i insert 45000.98 i expect 45000.98, but the number is rounded.

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    double a;
    cin >> a;   //if i insert 45000.98
    cout << a;   //output is 45001
    cout << endl << setprecision(2) << a;   //output is 4.5e+04
}
Gabry
  • 33
  • 1
  • 6
  • "*Why doubles round themselves?*" - because they are stored as approximations. – Fureeish Jun 23 '19 at 22:36
  • 2
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Borgleader Jun 23 '19 at 22:52
  • 1
    @Fureeish `double` has enough precision to store 7 decimal digits exactly. OP, the problem is that `cout` rounds to 6 digits by default. Try `setprecision(7)`. – HolyBlackCat Jun 23 '19 at 22:56
  • @HolyBlackCat "*`double` has enough precision to store 7 decimal digits exactly*" - that depends on how large or how small the value is. It is an approximation and sometimes it can't even handle the integer differences. For example, given `double max = std::numeric_limits::max(); double x = max - 5;`, `max == x` will yield `true`. But I do agree that this is not the case here and the problem lies in rounding which can be solved by `setprecision`. My comment is indeed slightly offtopic regarding the quesion, though. – Fureeish Jun 23 '19 at 23:08
  • @Fureeish *"it can't even handle the integer differences"* I didn't say '7 decimal digits after `.`' or '7 decimal digits right before `.`'. :P – HolyBlackCat Jun 23 '19 at 23:16
  • @HolyBlackCat that's almost fair :p – Fureeish Jun 23 '19 at 23:17
  • @Borgleader The current precision is low enough that the intrinsic rounding error of floating point representations does not play a role. – JaMiT Jun 24 '19 at 04:11

2 Answers2

1

Double type has 11 bits for exponent and 52 bits for the fractional part, more than enough to give you enough precision to represent 45000.98, but setprecision argument, as far as i recall, receives a characters limit, not the number of digits after decimal point. Use setprecision(8) and you should see 45000.98 as you probably expect.

Boris Lipschitz
  • 1,514
  • 8
  • 12
0

The double did not round itself; the streaming operation rounded the value — first by default, and later according to your instructions. You requested that your value be rounded to 2 digits of precision, and that's what you got (just the first two digits: 4.5e+04). You are getting scientific notation because you have not requested enough digits to reach the decimal point.

If you want to see all 7 digits of 45000.98 then request at least 7 digits of precision. (You may want to stay under 17 digits though, since that's where you start seeing the artifacts of the floating point representation.)

JaMiT
  • 14,422
  • 4
  • 15
  • 31