以下代码是否可以在具有符合ANSI标准的C编译器的所有环境中工作?
double n = 0;
assert(n == 0);
C ++怎么样?
答案 0 :(得分:5)
您不会询问0.0
是否总是完全代表。
在语句assert(n == 0)
中,0
在比较发生之前转换为double
。因此,只有在0
从int
转换为double
时,才能触发断言。这是一个比你所要求的要弱得多的限制,几乎可以肯定(尽管我不能想到一个标准参考来保证它不在我的头顶)。
关于你想问的问题:
正如其他人提到的,C标准并不要求浮点类型映射到IEEE-754,但我不知道任何C编译器使用的浮点表示没有精确的零表示。也就是说,对于C实现而言,使用double
的格式并不完全为零是“合法的”。
答案 1 :(得分:5)
C标准确实对浮点值的表示方式施加了一些限制。在§5.2.4.2.2浮动类型的特征中,浮点数必须表现出类似于模型定义的特征:
x = sb e Σ k = 1..p f k b -k
其中:
在此模型下,零总是能够准确表示 - 它只需要将所有有效位数 f k 设为零。
鉴于§6.3.1.4中的以下限制:
当整数类型的值为 转换为真正的浮动类型,如果 转换的值可以是 完全代表新类型, 它没有变化。
因此,当从整数0转换为浮点类型时,零必须始终保持不变。因此,断言必须始终保持。
答案 2 :(得分:2)
比较会将整数提升为double。您要问的是,每次将相同的整数转换为double时,编译器是否保证执行相同的转换。我相信它是。
不仅如此,任何足够小的整数都可以用double精确表示。我无法想象任何编译器会在那种情况下进行转换,但这并不精确。
答案 3 :(得分:1)
C99不强制要求IEEE754,只推荐它。 IEEE 754兼容编译平台可以定义符号(附件F)。 如果编译器定义了这个符号,那么肯定断言将保持不变。当文字常量完全可以表示为浮点数时,那么这个浮点数就是你在编译程序中必须得到的数字。
我想不出任何没有零的非IEEE 754浮点系统,或者没有理由不将源代码中的文字0
映射到它。