我一直在研究一些用于创建直方图的简单代码,并发现以下代码:
double value = 1.2;
double bucketSize = 0.4;
double bucketId = value / bucketSize;
std::cout << "bucketId as double: " << bucketId << std::endl;
std::cout << "bucketId as int: " << int(bucketId) << std::endl;
导致疯狂输出:
bucketId as double: 3
bucketId as int: 2
这基本上破坏了我对计算机的信任 ;) 在创建直方图时为 value
寻找正确的 bucketId
时。
我知道存在舍入误差等问题,但是否有针对该问题的通用解决方案?
(以防万一)请不要建议在转换为 int
之前将 0.5
添加到除法结果中,因为显然它在某些情况下效果不佳(例如 double value = 3; double bucketSize = 2;
)
提前致谢。
最佳答案
我或多或少基于您对其他人的一些评论。
要获取整数部分,解决方案是使用 modf
。但是
1.2/0.4
的整数部分很可能是 2
,而不是 3
;
0.4
不能用机器 float 表示(大多数
他们,至少),所以你除以非常接近的东西
0.4
。
真正的问题是您真正想要什么。如果你正在寻找
酌情决定(是否存在这样的词)取决于
bucketSize
,那么正确的做法是使用
到处都是缩放整数:
int value = 12;
int bucketSize = 4;
int bucketId = value / bucketSize;
然后:
std::cout << "bucketId as double: " << bucketId / 10.0 << std::endl;
std::cout << "bucketId as int: " << bucketId / 10 << std::endl;
否则,如果您想将值保持为 double ,您将
必须决定转换为 int
的接近程度,
然后使用你自己的函数:
int
asInt( double d )
{
double results;
double frac = modf( d, &results );
if ( frac > 1.0 - yourEpsilonHere ) {
results += 1.0;
}
return results;
}
由您决定什么值适合
你的EpsilonHere
;这取决于应用程序。 (有一次
我使用了这种技术,我们使用了 1E-9
。那并不意味着
但是,它适合您。)
关于c++ - 我如何信任从 double 到整数的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26488480/