这个x ==(int)(float)x总是如此吗?

时间:2014-02-11 13:46:32

标签: c floating-point

xint

我认为x==(int)(float)x始终是真的,但当xTMax时,该书说它是假的。 我在x=TMax时检查过它,它仍然是真的。这本书错了吗?

5 个答案:

答案 0 :(得分:2)

float具有IEEE-754浮点格式的24位精度。只要整数值具有更高的精度,就会失去精度。在具有32位int s的系统上尝试相同的操作,您将看到差异。

例如,点击

#include <stdio.h>

int main()
{
    unsigned int x = 4000000003U;
    float y = x;
    printf ("%u %.20g %.20g %u\n", x, (float)x, y, (unsigned int)(float)x);
}

将这个大数字转换为浮点数。这个浮点数不能保持整数,所以它接近它。

转换回int后,您会获得不同的价值。

至少,你应该得到一个,但我不能在我的系统上重现这个:上面的程序输出

4000000003 4000000003 4000000000 4000000003

虽然我预计第二个数字等于第三个......

但是,如果我将代码更改为64位整数:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
    uint64_t x = 400000000000000003U;
    double y = x;
    printf ("%" PRIu64 " %.20g %.20g %" PRIu64 "\n", x, (double)x, y,
(uint64_t)(double)x);
}

它将按预期工作:64位甚至超过double可以容纳(这将是53位),因此它可以按原样工作。

答案 1 :(得分:1)

不一定是这样,因为随着您增加值的大小,浮点会失去精度。

答案 2 :(得分:1)

假设使用IEEE-754,单精度float只能在2 24 内准确表示整数,但int在现代计算机中通常为32位,范围之外的整数可能不会被(int)(float)x

强制转回

如果使用double而不是float,则x == (int)(double)x对于所有32位整数都为真,因为double可以表示2 53内的整数

答案 3 :(得分:0)

tczf,你必须阅读CSAPP这本书,我想你可以看一下练习题2.49,这是在144页。带有n位分数的浮点格式不能代表整数它大于2 ^(n + 1)-1,因为它会失去精度。

因此,IEEE 754单精度浮点格式具有23位分数,而“int”类型具有32位,因此如果整数大于2 ^ 24-1,则float类型不能完全代表它。但是双浮点格式可以,因为它有52位分数。

答案 4 :(得分:0)

@ FatSheep的答案有误。

  

具有n位小数的浮点格式不能表示大于2 ^(n + 1)-1的整数,因为它将失去精度。

不是2^(n+1)-1,正确的是which larger than or equal to 2^(n+1) + 1

n + 1表示归一化值隐含前导1,并且有效位数等于M = 1 + f,f代表分数。 该代码将为您提供帮助。

#include<stdio.h>
#include<limits.h>

int main(){
    for(int i =0; i < INT_MAX; i++){
        int x = i;
        int y = (int)(float)x;//when x >= 2^(n + 1) + 1, x != y
        if(x != y){
            printf("%d,%d\n",x,y);
            break;
        }  
    }
    return 0;
}
相关问题