除以零:在 C 和/或 C++ 中定义的未定义行为或实现?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3004095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Division by zero: Undefined Behavior or Implementation Defined in C and/or C++?
提问by SiegeX
Regarding division by zero, the standards say:
关于除以零,标准说:
C99 6.5.5p5 - The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.
C++03 5.6.4 - The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined.
C99 6.5.5p5 - / 运算符的结果是第一个操作数除以第二个操作数的商;% 运算符的结果是余数。在这两个操作中,如果第二个操作数的值为零,则行为未定义。
C++03 5.6.4 - 二进制 / 运算符产生商,二进制 % 运算符产生第一个表达式除以第二个表达式的余数。如果 / 或 % 的第二个操作数为零,则行为未定义。
If we were to take the above paragraphs at face value, the answer is clearly Undefined Behaviorfor both languages. However, if we look further down in the C99 standard we see the following paragraph which appears to be contradictory(1):
如果我们从表面上看上面的段落,答案显然是两种语言的未定义行为。但是,如果我们进一步查看 C99 标准,我们会看到以下段落似乎是矛盾的 (1):
C99 7.12p4 - The macro INFINITY expands to a constant expression of type float representing positive or unsigned infinity, if available;
C99 7.12p4 - 宏 INFINITY 扩展为 float 类型的常量表达式,表示正无穷大或无符号无穷大(如果可用);
Do the standards have some sort of golden rulewhere Undefined Behavior cannot be superseded by a (potentially) contradictory statement? Barring that, I don't think it's unreasonable to conclude that if your implementation defines the INFINITY macro, division by zero is defined to be such. However, if your implementation does notdefine such a macro, the behavior is Undefined.
标准是否有某种黄金法则,即未定义行为不能被(可能)矛盾的陈述所取代?除此之外,我认为如果您的实现定义了 INFINITY 宏,则除以零被定义为这样的结论是不合理的。但是,如果您的实现没有定义这样的宏,则行为是未定义的。
I'm curious what the consensus is (if any) on this matter for each of the two languages. Would the answer change if we are talking about integer division int i = 1 / 0
versus floating point division float i = 1.0 / 0.0
?
我很好奇这两种语言中的每一种在这个问题上的共识是什么(如果有的话)。如果我们谈论整数除法int i = 1 / 0
与浮点除法,答案会改变float i = 1.0 / 0.0
吗?
Note (1)The C++03 standard talks about the <cmath>
library which includes the INFINITY macro.
注 (1)C++03 标准讨论了<cmath>
包含 INFINITY 宏的库。
回答by Péter T?r?k
I don't see any contradiction. Division by zero is undefined, period. There is no mention of "... unless INFINITY is defined"anywhere in the quoted text.
我看不出有什么矛盾。除以零是不确定的,句号。在引用的文本中的任何地方都没有提到“...除非定义了 INFINITY”。
Note that nowhere in mathematics it is defined that 1 / 0 = infinity. One mightinterpret it that way, but it is a personal, "shortcut" style interpretation, rather than a sound fact.
请注意,数学中没有任何地方定义 1 / 0 =无穷大。人们可能会这样解释它,但这是一种个人的“捷径”风格解释,而不是一个可靠的事实。
回答by Franti?ek ?ia?ik
1 / 0 is not infinity, only
1 / 0 不是无穷大,只有
lim 1/x = ∞ (x -> +0)
回答by wcochran
This was not a math purest question, but a C/C++ question.
这不是一个最纯粹的数学问题,而是一个 C/C++ 问题。
- According to the IEEE 754 Standard, which all modern C compilers / FPU's use, we have
- 3.0 / 0.0 = INF
- 0.0 / 0.0 = NaN
- -3.0 / 0.0 = -INF
- 根据所有现代 C 编译器/FPU 使用的 IEEE 754 标准,我们有
- 3.0 / 0.0 = INF
- 0.0 / 0.0 = NaN
- -3.0 / 0.0 = -INF
The FPU will have a status flag that you can set to generate an exception if so desired, but this is not the norm.
FPU 将有一个状态标志,如果需要,您可以将其设置为生成异常,但这不是常态。
INF can be quite useful to avoiding branching when INF is a useful result. See discussion here
当 INF 是有用的结果时,INF 对于避免分支非常有用。请参阅此处的讨论
http://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
http://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
回答by unwind
Why would it?
为什么会呢?
That doesn't make sense mathematically, it's not as if 1/xis defined as ∞ in mathematics in general. Also, you would at least need two more cases: -1/xand 0/xcan't also equal ∞.
这在数学上没有意义,一般来说,1/ x在数学中并不是被定义为 ∞ 的。此外,您至少还需要两种情况:-1/ x和 0/ x不能也等于 ∞。
See division by zeroin general, and the section about computer arithmeticin particular.
回答by supercat
Implementations which define __STDC_IEC_559__
are required to abide by the requirements given in Annex F, which in turn requires floating-point semantics consistent with IEC 60559. The Standard imposes no requirements on the behavior of floating-point division by zero on implementations which do not define __STDC_IEC_559__
, but does for those which do define it. In cases where IEC 60559 specifies a behavior but the C Standard does not, a compiler which defines __STDC_IEC_559__
is required by the C Standard to behave as described in the IEC standard.
定义的实现__STDC_IEC_559__
需要遵守附录 F 中给出的要求,这反过来又需要与 IEC 60559 一致的浮点语义。该标准没有对没有定义的实现的浮点除以零的行为强加任何要求__STDC_IEC_559__
,但对于那些确实定义它的人来说。在 IEC 60559 指定行为而 C 标准没有规定的情况下,C 标准__STDC_IEC_559__
要求定义的编译器按照 IEC 标准中的描述运行。
As defined by IEC 60559 (or the US standard IEEE-754) Division of zero by zero yields NaN, division of a floating-point number by positive zero or literal constant zero yields an INF value with the same sign as the dividend, and division of a floating-point number by negative zero yields an INF with the opposite sign.
根据 IEC 60559(或美国标准 IEEE-754)的定义,零除以零产生 NaN,浮点数除以正零或字面常量零产生与被除数相同符号的 INF 值,然后除法一个浮点数除以负零产生一个符号相反的 INF。
回答by kennytm
I've only got the C99 draft. In §7.12/4 it says:
我只有 C99 草案。在 §7.12/4 中它说:
The macro
INFINITY
expands to a constant expression of type float representing positive or unsigned infinity, if available; else to a positive constant of type
float
that overflows at translation time.
宏
INFINITY
如果可用,扩展为表示正无穷大或无符号无穷大的 float 类型的常量表达式;else 类型
float
为在翻译时溢出的正常量。
Note that INFINITY
can be defined in terms of floating-point overflow, not necessarily divide-by-zero.
请注意,INFINITY
可以根据浮点溢出来定义,不一定要除以零。
回答by king_nak
For the INFINITY macro: there is a explicit coding to represent +/- infinity in the IEEE754 standard, which is if all exponent bits are set and all fraction bits are cleared (if a fraction bit is set, it represents NaN)
对于 INFINITY 宏:在 IEEE754 标准中有一个明确的编码来表示 +/- 无穷大,即如果所有指数位都被设置并且所有小数位都被清除(如果小数位被设置,它代表 NaN)
With my compiler, (int) INFINITY == -2147483648
, so an expression that evaluates to int i = 1/0
would definitely produce wrong results if INFINITIY was returned
使用我的编译器,如果返回 INFINITIY,则计算结果(int) INFINITY == -2147483648
为 的表达式int i = 1/0
肯定会产生错误的结果
回答by Jose_X
Bottom line, C99 (as per your quotes) does not say anything about INFINITY in the context of "implementation-defined". Secondly, what you quoted does not show inconsistent meaning of "undefined behavior".
最重要的是,C99(根据您的报价)在“实现定义”的上下文中没有说明关于 INFINITY 的任何内容。其次,您引用的内容并未显示“未定义行为”的不一致含义。
[Quoting Wikipedia's Undefined Behavior page] "In C and C++, implementation-defined behavior is also used, where the language standard does not specify the behavior, but the implementation must choose a behavior and needs to documentand observe the rules it chose."
[引用维基百科的未定义行为页面]“在 C 和 C++ 中,也使用实现定义的行为,其中语言标准没有指定行为,但实现必须选择一种行为,并且需要记录和遵守它选择的规则。”
More precisely, the standard means "implementation-defined" (I think only) when it uses those words with respect to the statement made since "implementation-defined" is a specific attribute of the standard. The quote of C99 7.12p4 didn't mention "implementation-defined".
更准确地说,该标准的意思是“实现定义的”(我认为只是),当它针对所做的陈述使用这些词时,因为“实现定义的”是标准的一个特定属性。C99 7.12p4 的引用没有提到“实现定义”。
[From C99 std (late draft)] "undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements"
[来自 C99 std(后期草案)]“未定义行为:在使用不可移植或错误的程序结构或错误数据时的行为,本国际标准对此不作任何要求”
Note there is "no requirement" imposed for undefined behavior!
请注意,对于未定义的行为,“没有要求”!
[C99 ..] "implementation-defined behavior: unspecified behavior where each implementation documents how the choice is made"
[C99 ..]“实现定义的行为:未指定的行为,其中每个实现都记录了如何做出选择”
[C99 ..] "unspecified behavior: use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance"
[C99 ..]“未指定的行为:使用未指定的值,或本国际标准提供两种或多种可能性并且在任何情况下都没有对选择的进一步要求强加的其他行为”
Documentation is a requirement for implementation-defined behavior.
文档是实现定义行为的必要条件。