在任何C编译器和机器上,0/0(NAN)和1/0(INF)的字节表示形式是否相同?

在任何C编译器和机器上,0/0(NAN)和1/0(INF)的字节表示形式是否相同?,c,math,C,Math,据我所知,您可以通过以下操作获得NaN和Inf: // this is no code, just IEEE-754 math n = 0 / 0 i = 1 / 0 现在,您可以检查两个变量的字节表示形式,如下所示: void dumpdouble(double x) { unsigned char *p = (unsigned char *) &x; int k; #ifndef BIG_ENDIAN for(k = 0; k < 8; k++) p

据我所知,您可以通过以下操作获得
NaN
Inf

// this is no code, just IEEE-754 math
n = 0 / 0
i = 1 / 0
现在,您可以检查两个变量的字节表示形式,如下所示:

void dumpdouble(double x) {
    unsigned char *p = (unsigned char *) &x;
    int k;
#ifndef BIG_ENDIAN
     for(k = 0; k < 8; k++) printf("%.2x", p[7-k]);
#else    
     for(k = 0; k < 8; k++) printf("%.2x", p[k]);
#endif 
    printf("\n");
}

int main(int argc, char *argv[]) {
    double n = (double) 0 / (double) atoi(argv[1]);
    double i = (double) 1 / (double) atoi(argv[1]);     
    dumpdouble(n);
    dumpdouble(i);
    return 0;
}
在使用Visual C 15 for x64的Windows 7上,结果如下:

fff8000000000000
7ff0000000000000
现在我想知道的是:


在任何符合IEEE-754标准的C编译器和体系结构上,使用64位双精度的0/0是否保证提供
$fff800000000
,使用64位双精度的1/0是否保证提供
$7ff0000000000000
,或者该机器/编译器-/无论什么特定的,我都不能依赖于产生上述结果的那些划分

0/0
1/0
是整数除法,它们会导致未定义的行为,因此不提供任何保证

C11 6.5.5p5-/运算符的结果是 第一个操作数除以第二个操作数;测试结果为% 运算符是余数。在这两种操作中,如果 第二个操作数为零,行为未定义


使用IEEE-754 math时,+INF只有一种编码,而-INF只有一种编码。因此,
/a.out 0
预计只会产生
1/(double)0
的一种+INF编码。根据double的endian(可能不同于
int
的endian),字节序列可能不同。由于未显示
BIG_ENDIAN
定义,因此只能希望它对于double是正确的。请注意,很少有机器可以使用大/小编码以外的其他编码


非数字编码有很多种
fff8000000000000
就是其中之一。其他兼容的编译器/运行可能会产生其他结果。e、 g.答案可能不同。

1/0
0/0
是整数除法,它们会导致未定义的行为。@Ayxan,因此答案是否定的:)。@BartFriederichs Well,因为您的评论而作为答案发布:)首先,您需要解决整数算术问题。因此,符合IEEE-754并不保证C实现将
double
映射到IEEE-754二进制64格式,它可以是二进制128甚至十进制格式。C标准的可选附录F保证了这一点。让我们假设一下。字节顺序不能保证是大端或小端。它可能是混合的。(例如,一个实现可能是一个四字节字内的小尾端,但以大尾端顺序存储字。)这是很常见的,您会得到显示的结果,但不能保证。@EricPostFischil:请检查更新的代码。我接受这个答案,因为它是关于NaN和INF的字节表示。当然,Ayxan还说得对,严格地说,除以0在C中是未定义的(虽然我尝试过的所有编译器在上述情况下似乎都会产生INF和NaN,但当然不能保证)
fff8000000000000
7ff0000000000000