除以零:未定义的行为或实现在C和/或C++中定义?

Sie*_*geX 24 c c++ divide-by-zero undefined-behavior

关于除零,标准说:

C99 6.5.5p5 - /运算符的结果是第一个操作数除以第二个操作数的商; %运算符的结果是余数.在这两个操作中,如果第二个操作数的值为零,则行为未定义.

C++ 03 5.6.4 - 二进制/运算符产生商,二进制%运算符从第一个表达式除以第二个表达式得到余数.如果/或%的第二个操作数为零,则行为未定义.

如果我们将上述段落视为面值,答案显然是两种语言的未定义行为.但是,如果我们进一步了解C99标准,我们会看到以下段落似乎是矛盾的(1):

C99 7.12p4 - 宏INFINITY扩展为float类型的常量表达式,表示正无穷大或无符号无穷大(如果可用);

标准是否有某种黄金法则,其中未定义的行为不能被(可能)矛盾的陈述所取代?除此之外,我认为如果你的实现定义了INFINITY宏,那么将零除法定义为这样是不合理的.但是,如果您的实现没有定义这样的宏,则行为是Undefined.

我很好奇这两种语言在这个问题上的共识是什么(如果有的话).如果我们谈论整数除法int i = 1 / 0与浮点除法,答案会改变float i = 1.0 / 0.0吗?

注意(1) C++ 03标准讨论了<cmath>包含INFINITY宏的库.

Pét*_*rök 25

我没有看到任何矛盾.除以零是未定义的,期间.在引用文本中的任何地方都没有提到"......除非定义INFINITY".

请注意,在数学中没有定义1/0 = 无穷大.有人可能会这样解释,但这是一种个人的"捷径"式解释,而不是一个合理的事实.


Fra*_*čik 11

1/0只是无穷大

lim 1/x = ? (x -> +0)

  • ......鉴于这个问题,这是一个非常有效的答案. (15认同)
  • 这是不正确的,只有当x被限制为正值时才会出现这种情况. (9认同)
  • 这个答案与编程无关. (3认同)
  • @Pete Alexander的问题是"除以零:未定义的行为或在C和/或C++中定义的实现?",而不是标准中的行为是否与数学概念一致.该标准使用HUGE_VAL作为此类限制,这与IEE745实现中的无穷大相同. (3认同)
  • @Pete Kirkham:嗯,有一个标准回答了这个问题,另一个标准与第一个标准并不矛盾,并且仅由于错误的数学推定才假定了这个矛盾,所以我认为拒绝这种推定会使答案清楚。 (2认同)

wco*_*ran 8

这不是一个最纯粹的数学问题,而是一个 C/C++ 问题。

  • 根据所有现代 C 编译器/FPU 使用的 IEEE 754 标准,我们有
    • 3.0 / 0.0 = INF
    • 0.0 / 0.0 = NaN
    • -3.0 / 0.0 = -INF

FPU 将有一个状态标志,如果需要,您可以将其设置为生成异常,但这不是常态。

当 INF 是有用的结果时,INF 对于避免分支非常有用。请参阅此处的讨论

http://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF