双精度 0.0 在可移植 C 中总是精确表示吗?
以下代码是否可以在具有 ANSI 兼容 C 编译器的所有环境中运行?
double n = 0;
assert(n == 0);
那么 C++ 呢?
Can the following code be expected to work in all environments that have an ANSI-compliant C compiler?
double n = 0;
assert(n == 0);
What about C++?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C 标准确实对浮点值的表示方式施加了一些限制。在§5.2.4.2.2 浮点类型的特征中,浮点数必须表现出如同模型定义的特征:
其中:
在这个模型下,零总是能够被精确地表示 - 它只需要所有有效数字fk为零。
鉴于第 6.3.1.4 节中的以下限制:
由此可见,当从整数 0 转换为浮点类型时,零必须始终保持不变。因此,该断言必须始终成立。
The C standard does put some limitations on how floating point values are represented. In §5.2.4.2.2 Characteristics of floating types, floating point numbers must exhibit characteristics as if they were defined by the model:
Where:
Under this model, zero is always able to be exactly represented - it simply requires all the significand digits fk to be zero.
Given the following restriction in §6.3.1.4:
It follows that zero must always be unchanged when converted from the integer 0 to a floating point type. Therefore the assertion must always hold.
您并不是在问
0.0
是否始终准确表示。在语句
assert(n == 0)
中,在比较发生之前,0
被转换为double
。因此,只有在将0
从int
转换为double
不可重现时,才能触发断言。这是一个比您所询问的限制要弱得多的限制,并且几乎肯定会成立(尽管我无法想到标准参考来保证它脱离我的头脑)。对于您想问的问题:
正如其他人提到的,C 标准不要求浮点类型映射到 IEEE-754,但我不知道任何没有 C 编译器的浮点表示形式零的精确表示。也就是说,对于 C 实现来说,使用没有精确零的 double 格式是“合法的”。
You're not asking if
0.0
is always represented exactly.In the statement
assert(n == 0)
,0
is converted todouble
before the comparison occurs. Thus, the assert can only be triggered if converting0
fromint
todouble
is not reproducible. This is a much weaker restriction than what you're asking about, and will almost certainly hold (though I can't think of a standards reference to guarantee it off the top of my head).To the question you intended to ask:
As others mentioned, the C standard does not require that floating-point types map to IEEE-754, but I am not aware of any floating-point representation used with any C compiler that does not have an exact representation of zero. That said, it would be "legal" for a C implementation to use a format for
double
that did not have an exact zero.比较会将整数提升为双精度。您要问的是,编译器是否保证每次将相同的整数转换为双精度时都会执行相同的转换。我相信是的。
不仅如此,任何足够小的整数都可以用 double 精确表示。我无法想象任何编译器会在这种情况下进行不精确的转换。
The comparison will promote the integer to a double. What you're asking is if the compiler is guaranteed to do identical conversions each time it converts identical integers to double. I believe it is.
Not only that, any small enough integer can be exactly represented by a double. I can't imagine any compiler that would do a conversion in that case that wasn't precise.
C99 不强制要求 IEEE754,只是推荐它。 IEEE 754 兼容编译平台可以定义一个符号(附录 F)。
如果编译器定义了这个符号,那么是的,断言将保证成立。当文字常量可以精确地表示为浮点数时,那么这个浮点数就是您必须在编译的程序中获得的值。
我想不出任何非 IEEE 754 浮点系统没有零,也没有理由不将源代码中的文字
0
映射到它。C99 does not mandate IEEE754, only recommends it. There is a symbol that IEEE 754 compliant compilation platforms can define (Annex F).
If the compiler defines this symbol, then yes, the assertion would be guaranteed to hold. When the literal constant is representable exactly as a floating-point number, then this floating-point number is what you must get in the compiled program.
I cannot think of any non-IEEE 754 floating-point system that wouldn't have a zero, or a reason not to map the literal
0
in the source code to it.