我认为实现这一点的最佳方法是依靠以下事实:根据 IEEE 754 浮点标准,浮点位的整数表示按字典顺序排列为 2 补码整数。
即你可以简单地添加一个ulp(最后一个单位)来获得下一个浮点表示(如果它更小,它总是会比你的阈值略大,因为圆形误差最多为1/2 ulp)
例如
float floatValue = 7.f/10;
std::cout << std::setprecision(20) << floatValue << std::endl;
int asInt = *(int*)&floatValue;
asInt += 1;
floatValue = *(float*)&asInt;
std::cout << floatValue << std::endl;
打印(在我的系统上)
0.69999998807907104492
0.70000004768371582031
floor要知道何时需要添加一个ulp ,您必须依赖floor
if (std::floor(floatValue * 100.) != std::floor(floatValue * 100. + 0.5)) {
int asInt = *(int*)&floatValue;
asInt += 1;
floatValue = *(float*)&asInt;
}
将正确地将 0.69.. 转换为 0.70.. 但不理会 0.80..。
100.请注意,在应用之前,浮点数通过与乘法提升为双精度floor。
如果你不这样做,你就有可能陷入这样的境地
7.f/10.f * 100.f
(精度有限)浮点表示将是 70.00...