两个相等值的双倍保证具有相同的位模式吗?

时间:2016-10-07 03:06:40

标签: c floating-point bit-manipulation

在C中,是否保证两个值相等的双精度(double1 == double2)具有相同的位模式?

2 个答案:

答案 0 :(得分:6)

没有这样的保证。

例如,在IEEE floating point format中,存在负0的概念。它比较等于正0但具有不同的表示。

以下是一个例子:

#include <stdio.h>

int main()
{
    unsigned long long *px, *py;
    double x = 0.0, y = -0.0;
    px = (unsigned long long *)&x;
    py = (unsigned long long *)&y;

    printf("sizeof(double)=%zu\n",sizeof(double));
    printf("sizeof(unsigned long long)=%zu\n",sizeof(unsigned long long));

    printf("x=%f,y=%f,equal=%d\n",x,y,(x==y));
    printf("x=%016llx,y=%016llx\n",*px,*py);

    return 0;
}

输出:

sizeof(double)=8
sizeof(unsigned long long)=8
x=0.000000,y=-0.000000,equal=1
x=0000000000000000,y=8000000000000000

编辑:

这是一个不依赖于类型惩罚的修订示例:

#include <stdio.h>

void print_bytes(char *name, void *p, size_t size)
{
    size_t i;
    unsigned char *pdata = p;
    printf("%s =", name);
    for (i=0; i<size; i++) {
        printf(" %02x", pdata[i]);
    }
    printf("\n");
}

int main()
{
    double x = 0.0, y = -0.0;

    printf("x=%f,y=%f,equal=%d\n",x,y,(x==y));
    print_bytes("x", &x, sizeof(x));
    print_bytes("y", &y, sizeof(y));

    return 0;
}

输出:

x=0.000000,y=-0.000000,equal=1
x = 00 00 00 00 00 00 00 00
y = 00 00 00 00 00 00 00 80

你可以在这里看到两者之间的代表性差异。一个有符号位设置而另一个没有。

答案 1 :(得分:0)

是的,零除外。只有一种方法可以表示特定的IEEE浮点值或双精度值。如果有两种方法来表示相同的值,那么这将是浪费的,IEEE格式非常有效。

零是一种特殊情况,因为正负值为零,它们将相等,并且它们在大多数情况下是相等的。有一些罕见的情况(1/0)会给出不同的结果 - 正无穷大。

之前的回答不必要地集中在零案例上,据我所知,未能回答其他40亿花车和1600亿双打的案例。