I had this C++ code:
int x;
double y;
// do sth
int z = ceil(x*y);
If x = 410
, y = 1.1
, then z = 452
when it should've been 451
. I changed to z = ceil(float(x*y))
and it works. My friend suggests z = ceil(double(x)*y)
instead. Are there any differences between the 2 definition of z
and which one should I use?
Also what does x*y
do? I suspect it is equivalent to float(x)*y
but I'm not so sure.
x * y
simply multiplies the two variables. This implicitly does a type conversion, in this case converting the int value of 410
to the double value 410.0
(because y
is a double) before doing the actual multiplication.
Because of this type conversion, your friend's suggestion is just a more explicit version of what your original code does. It yields the same result, i.e. it will give 452
.
If x = 410, y = 1.1, then z = 452 when it should've been 451
True, by real world calculus. However, doubles and floats in computers have finite precision. If you print with increased precision:
printf("%.15f\n", (x * y)); // -> 451.000000000000057
You'll agree that when ceil
ing this, it yields 452
.
The reason ceil(float(x * y))
works is entirely by accident; because a float
has lower precision than a double
, this happens to round x * y
to 451.000000...
.
You can't rely on floating point arithmetic to produce exactly the results you'd expect in the real world, and the ceil
can make that very much apparent in scenario's like the one you give.
Without further information on the underlying problem you're trying to solve, I can't give further direction on what you could do.