我可以信任代表整数的浮点数或双精度数来保持精度吗?

时间:2018-11-02 02:01:17

标签: c++ floating-point precision

如果我有两个表示精确整数的随机浮点数或双精度数(在32位整数的范围内),我是否可以期望它们之间的任何和所有加法,减法和乘法运算产生整数浮点数/双精度数而无小数部分?

float x = randInt();
float y = randInt();
float resultAdd = x + y;
float resultSub = x - y;
float resultMul = x * y;
if(fract(resultAdd) == 0.f && fract(resultSub) == 0.f && fract(resultMul) == 0.f){
    // will this section always execute, assuming no overflow occurred?
}

每个人都知道永远不要相信浮点精度,但是我想在适当的地方重建信任。鉴于某些解释语言(不明智地)使用浮点数/双精度数作为通用“数字”类型的基础,因此重要的是要知道哪些操作可以将浮点数的状态保留为整数。

2 个答案:

答案 0 :(得分:2)

IEEE-754单精度float仅具有24位尾数,因此显然不能完全表示32位范围内的所有整数

例如,如果x = 16777216.0f,y = 1.0f,则x + y不等于16777217

OTOH IEEE-754双精度具有53位尾数,因此它可以精确地表示每个32位整数。这就是为什么某些语言(例如Javascript或Lua)的所有数值都只有两倍

请参见Are all integer values perfectly represented as doubles?

答案 1 :(得分:0)

  

重要的是要知道哪些操作可以将浮点数的状态保留为整数。

IEEE-754要求加法,减法,乘法,除法和平方根必须尽可能精确(这是IEEE-754 2008的引用):

  

每个返回a的计算操作   执行本标准规定的数值结果,就好像它首先产生了中间结果一样   校正至无限精度且范围无限制,然后将中间结果四舍五入,如果   必要,以适合目的地的格式。

因此,如果abs(result)小于或等于2 24 (对于浮点型)或2 53 (对于双精度型),则会很精确的。

注意:整数浮点值的加,减和乘积将始终导致整数(无论范围如何),但可能不精确(如果结果超出了前面提到的范围)。