安全地反转浮点计算

时间:2017-05-23 11:56:53

标签: c++ floating-point rounding-error

我想知道反转这个计算的正确方法是什么:

float x = a * 25.0f + b; // where a and b are integers and b is in [0-25[

如何避免可能的浮点舍入错误。即使x有一些错误,答案也很明显,因此应该可以实现。

2 个答案:

答案 0 :(得分:1)

对于你给出的范围,你无法安全地回来。

对于a = 10 ^ 6,您需要20位。如果乘以25,则需要再多5位。因此,对于a的极值,您需要25位有效数来表示x。 IEEE 754单精度浮点数仅为您提供24.这意味着x可能会丢失最低有效位。而不是真值x,你有x +/- 1。

但您可以访问更多信息:

  • 如果x <2 ^ 24,那么你知道你可以通过朴素算法检索b和a
  • 如果x> = 2 ^ 24并且有效数字是奇数((int)(x))%4 == 2,那么您就知道没有进行舍入。实际上,取消最后一位是精确平局的情况,即使在IEEE 754默认舍入模式下也会导致舍入到最接近的位置。
  • 仅在x&gt; = 2 ^ 24且有效数字为偶数的情况下,您无法得出结论,并且您有3个可能的值{a,b}。

结论:你应该在这里使用双精度

答案 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足够小以投放到intx = 1e30f肯定会失败。