在任何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