我有以下代码将double
投射到int
:
double dblValue = 7.30;
int intValue = (int)(dblValue*100); //I want intValue to store extactly 730;
cout << intValue;
输出:729
I know that the compiler is reading dblValue as 7.2999999 before casting it to int.
我的问题是:是否可以通过阻止向下舍入错误将其强制转换为730?
如果您的解决方案避免使用C ++ 11或其他预定义函数,那将是最好的。我在这里使用的唯一预处理器指令是<iostream>
。
答案 0 :(得分:18)
将非整数(在数学意义上)的数字转换为整数时,无法阻止舍入错误,您唯一能做的就是尝试实现正确的舍入。
实现合理(尽管不完美)舍入的最简单方法如下:
int intValue = (int)(dblValue < 0 ? dblValue - 0.5 : dblValue + 0.5);
当然,既然你的问题被c++
和casting
标记了,我无法抗拒用c ++风格的演员代替你的c风格演员:
int intValue = static_cast<int>(dblValue < 0 ? dblValue - 0.5 : dblValue + 0.5);
答案 1 :(得分:1)
您可以定义自己的整数截断函数,以尽可能小的值增加值,以确保舍入结果超过整数阈值。
#include <limits>
int int_cast(double x)
{
return (int)(x * (1.0 + std::numeric_limits<double>::epsilon()));
}
如果您不想依赖<limits>
,可以使用DBL_EPSILON
中的<float.h>
或替换您自己的非常小的号码。另请参阅this question。
答案 2 :(得分:0)
这不是任何类型的错误,它是计算机存储浮点值的方式。 你可以这样做:
int intValue = (int)(dblValue*100 + 0.00001);
答案 3 :(得分:-1)
C ++ 11添加了lround,有助于避免隐式double到long截断强制转换的精度损失:
int intValue = (int) lround(dblValue*100)
long
对int
施放也不会失去精确度。
不幸的是,没有iround()
。
<强>更新强>
我猜没有iround()
,因为任何32位整数都将完全适合64位双精度的52 precision bits。因此,在直接双截断到int截断时不存在精度损失的可能性:
int intValue = (int) round(dblValue*100)