我有这个 C++ 代码:
int x;
double y;
// do sth
int z = ceil(x*y);
如果
x = 410
,y = 1.1
,则 z = 452
,而本应是 451
。我改为z = ceil(float(x*y))
并且有效。我的朋友建议改为z = ceil(double(x)*y)
。 z
的 2 种定义之间有什么区别,我应该使用哪一种?
还有
x*y
有什么作用?我怀疑它相当于float(x)*y
,但我不太确定。
x * y
只是将两个变量相乘。这会隐式执行类型转换,在本例中,在进行实际乘法之前将 410
的 int 值转换为 double 值 410.0
(因为 y
是双精度型)。
由于这种类型转换,您朋友的建议只是您原始代码的更明确版本。它产生相同的结果,即它将给出
452
。
如果 x = 410,y = 1.1,则 z = 452,而它应该是 451
确实如此,通过现实世界的计算。然而,计算机中的双精度数和浮点数的精度是有限的。如果您提高打印精度:
printf("%.15f\n", (x * y)); // -> 451.000000000000057
您会同意,当
ceil
执行此操作时,它会产生 452
。
ceil(float(x * y))
起作用的原因完全是偶然;因为 float
的精度低于 double
,所以这会将 x * y
舍入为 451.000000...
。
您不能依靠浮点运算来准确产生您在现实世界中期望的结果,而
ceil
可以在场景中使这一点非常明显,就像您给出的那样。
如果没有有关您要解决的根本问题的更多信息,我无法就您可以做什么提供进一步的指导。