如何进行带有偏差的浮点舍入(始终向上或向下舍入)?
我想以偏置舍入浮动,要么总是向下,要么总是向上。 代码中有一个特定的点,我需要这个,程序的其余部分应该像往常一样四舍五入到最接近的值。
例如,我想四舍五入到最接近的 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++ 编程。
I want to round floats with a bias, either always down or always up. There is a specific point in the code where I need this, the rest of the program should round to the nearest value as usual.
For example, I want to round to the nearest multiple of 1/10. The closest floating point number to 7/10 is approximately 0.69999998807, but the closest number to 8/10 is approximately 0.80000001192. When I round off numbers, these are the two results I get. I'd rather get them rounded the same way. 7/10 should round to 0.70000004768 and 8/10 should round to 0.80000001192.
In this example I am always rounding up, but I have some places where I want to always round down. Fortunately, I am only dealing with positive values in each of these places.
The line I am using to round is floor(val * 100 + 0.5) / 100
. I am programming in C++.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为实现这一点的最佳方法是依赖这样一个事实:根据 IEEE 754 浮点标准,浮点位的整数表示按字典顺序排序为 2 补码整数。
即,您可以简单地添加一个 ulp(最后一个位置的单位)来获取下一个浮点表示(如果阈值较小,则它总是比您的阈值稍大,因为舍入误差最多为 1/2 ulp),
例如
打印(在我的系统上)
要知道何时需要添加一个 ulp,您必须依赖
floor
和圆角floor
之间的差异,才能正确转换 0.69..到 0.70.. 但保留 0.80..。
请注意,在应用
floor
之前,通过与100.
相乘,浮点数会提升为双精度。如果您不这样做,您可能会面临这样的情况:(
精度有限)浮点表示将为 70.00...
I think the best way to achieve this is to rely on the fact that according to the IEEE 754 floating point standard, the integer representation of floating point bits are lexicographically ordered as a 2-complement integer.
I.e. you could simply add one ulp (units in the last place) to get the next floating point representation (which will always be slightly larger than your treshold if it was smaller, since the round error is at most 1/2 ulp)
e.g.
prints (on my system)
To know when you need to add one ulp, you'll have to rely on the difference of
floor
and a roundedfloor
Would correctly convert 0.69.. to 0.70.. but leave 0.80.. alone.
Note that the float gets promoted to a double via the multiplication with
100.
before thefloor
is applied.If you don't do this you risk getting in the situation that for
The (limited in precision) float representation would be 70.00...