我想要偏向于浮动,要么总是向下,要么总是向上。在我需要的代码中有一个特定点,程序的其余部分应该像往常一样舍入到最接近的值。
例如,我想要舍入到最接近的1/10的倍数。最接近7/10的浮点数约为0.69999998807,但最接近8/10的数字约为0.80000001192。当我舍入数字时,这是我得到的两个结果。我宁愿以同样的方式对它们进行四舍五入。 7/10应该舍入到0.70000004768,而8/10应该舍入到0.80000001192。
在这个例子中,我总是四处寻找,但我有一些地方,我想要总是向下舍入。幸运的是,我只是处理每个地方的正值。
我用来围绕的行是floor(val * 100 + 0.5) / 100
。我用C ++编程。
答案 0 :(得分:11)
我认为实现这一目标的最佳方法是依赖于这样的事实:根据IEEE 754浮点标准,浮点位的整数表示按字典顺序排列为2 - 补码整数。
即。你可以简单地添加一个ulp(最后一个单位)来获得下一个浮点表示(如果它更小,它总是略大于你的阈值,因为圆误差最多是1/2 ulp)
e.g。
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
要知道何时需要添加一个ulp,您必须依赖floor
和四舍五入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
的乘法将浮点数提升为double。
如果你不这样做,你就有可能陷入
的境地 7.f/10.f * 100.f
(精度有限)浮动表示将是70.00 ......