按整数划分保证产生相同的浮点数?

时间:2015-11-21 20:14:15

标签: c++ floating-point

我想知道当x和y是整数(但是浮点类型)时x / y是否保证产生与kx / ky相同的浮点值,其中k是整数。

那么,例如,1.0 / 3,2.0 / 6,3.0 / 9,......都产生相同的精确浮点数(一个与==运算符相同的那个)?

如果每种语言/平台不同,我对Linux上的c ++特别感兴趣。

3 个答案:

答案 0 :(得分:2)

只要k*xk*y操作准确(结果适合浮点),IEEE754标准就可以保证您获得最接近精确除法结果的浮点数

显然,由于精确数学中的(k*x)/(k*y)=(x/y),最近的浮点数对于两者都是相同的。

如果k*xk*y不适合浮动(浮点操作不准确),那么您就不会得到任何保证。

关于C ++保证的最低限度,我不知道,但你可以认为大多数平台都符合这些基本的IEEE754属性。

答案 1 :(得分:0)

如果计算以相同的精度完成,我认为它们最终会相同。但是,如果情况并非如此,则float-> double和double-> float转换都会产生差异。并且这不是一个不可能的场景(至少没有fp:strict),因为编译器可以混合FPU和SSE代码(例如,如果它需要调用未在SSE中实现的函数,或者将它用作cdecl函数的参数/返回结果。)

也就是说,你也可以创建一个商(x / y)类并将其用作关键字。您可以为它定义所有算术,例如

q0+q1 = (q0.x*q1.y+q1.x*q0.y)/(q0.y*q1.y)
q0<q1 = q0.x*q1.y*(q0.y*q1.y) < q1.x*q0.y*(q0.y*q1.y)

(在后一种情况下*(q0.y * q1.y)被添加以说明我们已经将原始表达式q0.x / q0.y&lt; q1.x / q1相乘的事实.y by q0.y * q1.y,如果它是否定的,&lt;将改为&gt;)。你也可以通过这种方式摆脱一些分歧。

答案 2 :(得分:-1)

我不知道保证,但是编译这个

int main() {
    int i = 0;
    float
        x = 1E20,
        y = 3E20,
        f = 10;
    while ( ++i <=20 ) {
        printf(" %d) %f = %f / %f\n", i, x / y, x, y );
        x *= f;
        y *= f;
    }
}

使用gcc -O0(在英特尔(R)Xeon(R)CPU E3-1246上的Debian GNU / Linux上)生成

 1) 0.333333 = 1.000000 / 3.000000
 2) 0.333333 = 1000.000000 / 3000.000000
 3) 0.333333 = 1000000.000000 / 3000000.000000
 4) 0.333333 = 1000000000.000000 / 3000000000.000000
 5) 0.333333 = 999999995904.000000 / 3000000053248.000000
 6) 0.333333 = 999999986991104.000000 / 3000000028082176.000000
 7) 0.333333 = 999999984306749440.000000 / 3000000159078678528.000000
 8) 0.333333 = 999999949672133165056.000000 / 3000000271228864561152.000000
 9) 0.333333 = 999999941790833817157632.000000 / 3000000329775659716968448.000000
 10) 0.333333 = 999999914697178458896728064.000000 / 3000000186813393145719422976.000000
 11) 0.333333 = 999999939489602493962365435904.000000 / 3000000196258126111458713403392.000000
 12) 0.333333 = 999999917124474831091725703839744.000000 / 3000000060858434314620245836300288.000000
 13) 0.333333 = 999999882462153731101078006664265728.000000 / 3000000043527273764624921987712548864.000000
 14) -nan = inf / inf