2

I want to have the right 6999 but the code prints 6998, is there any way to implement it in C/C++?

#include <iostream>
using namespace std;

int main() {
 double x = 69.99;
 int xi = x*100;
 cout << xi << endl;
 return 0;
}
phuclv
  • 37,963
  • 15
  • 156
  • 475
tiplip
  • 329
  • 5
  • 17
  • 1
    For a lot of detail on this, see [here](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). In this specific case you could use [std::round](https://en.cppreference.com/w/cpp/numeric/math/round) in the form of `int xi = std::round(x*100);` but depending on your actual situation the edge case subtleties may be trickier to root out. – Nathan Pierson Sep 18 '21 at 02:38
  • 2
    If you are dealing in 2 decimal points and always 2 decimal points, for example dollar money amounts, use integers and [fixed point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) so that you never have to deal with imprecision. – user4581301 Sep 18 '21 at 02:58
  • your code is not C. And there's no language called C/C++ – phuclv Sep 18 '21 at 04:09

1 Answers1

2

Your compiler is probably using the IEEE 754 double precision floating point format for representing the C++ data type double. This format cannot represent the number 69.99 exactly. It is stored as 69.989999999999994884. When you multiply this value with 100, the result is slightly smaller than 6999.

When implicitly converting floating-point numbers to integers, the number is always rounded towards zero (positive numbers get rounded down, negative ones get rounded up).

If you don't want to always round the result towards zero, you can change the line

int xi = x*100;

to

long xi = lround( x*100 );

which will not always round the number towards zero, but will instead always round it to the nearest integer.

Note that you must #include <cmath> to be able to use std::lround.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39