我想知道反转这个计算的正确方法是什么:
float x = a * 25.0f + b; // where a and b are integers and b is in [0-25[
如何避免可能的浮点舍入错误。即使x有一些错误,答案也很明显,因此应该可以实现。
答案 0 :(得分:1)
对于你给出的范围,你无法安全地回来。
对于a = 10 ^ 6,您需要20位。如果乘以25,则需要再多5位。因此,对于a的极值,您需要25位有效数来表示x。 IEEE 754单精度浮点数仅为您提供24.这意味着x可能会丢失最低有效位。而不是真值x,你有x +/- 1。
但您可以访问更多信息:
((int)(x))%4 == 2
,那么您就知道没有进行舍入。实际上,取消最后一位是精确平局的情况,即使在IEEE 754默认舍入模式下也会导致舍入到最接近的位置。结论:你应该在这里使用双精度
答案 1 :(得分:0)
尝试使用 modulo arithmetics ,即整数除法/
和余数%
:
int a = ((int) (x + 0.5f)) / 25;
int b = ((int) (x + 0.5f)) % 25;
如果x
可以汇总错误,例如x = 53.999997
代替54
,然后将转换为最接近的整数:(int) (x + 0.5f)
。请注意,x
应足够小以投放到int
:x = 1e30f
肯定会失败。