32

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.

If we were to take the above paragraphs at face value, the answer is clearly Undefined Behavior for both languages. However, if we look further down in the C99 standard we see the following paragraph which appears to be contradictory(1):

C99 7.12p4 - The macro INFINITY expands to a constant expression of type float representing positive or unsigned infinity, if available;

Do the standards have some sort of golden rule where 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 not define such a macro, the behavior is Undefined.

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 ?

Note (1) The C++03 standard talks about the <cmath> library which includes the INFINITY macro.

River
  • 8,585
  • 14
  • 54
  • 67
SiegeX
  • 135,741
  • 24
  • 144
  • 154
  • 1
    Here is another well-known joke: If x * 0 = y then how to find x ? – psihodelia Jun 09 '10 at 08:31
  • @paxdiablo: how have you canceled y/(xy) ? You must get 1/x, but not x – psihodelia Jun 09 '10 at 09:27
  • @psihodelia - i would say that x * 0 = y, find x would be the mathematical equivalent of a rhetorical question. x is anything or nothing, and therefore it has no answer while not requiring an answer just the same. – pxl Jun 09 '10 at 09:49
  • @paxdiablo: If you divide by `x` you have to assume `x != 0` as well. – u0b34a0f6ae Jun 09 '10 at 12:21
  • "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": this is indeed unreasonable, as C99 7.12p4 doesn't mention division. Anyway, assigning INFINITY isn't incompatible with UB. –  Oct 21 '16 at 15:09
  • 2
    I voted down, because in no way I see the second quote implying that INFINITY is the result of a division by zero, so the question is, in my opinion, ill-posed. – Antonio Oct 04 '17 at 18:10
  • 2
    Related [The behaviour of floating point division by zero](https://stackoverflow.com/questions/42926763/the-behaviour-of-floating-point-division-by-zero) – Antonio Oct 04 '17 at 18:19
  • @Antonio Duly noted and recorded as such. Good day sir! – SiegeX Oct 04 '17 at 19:13
  • I added a new answer to the question @Antonio references and it has a lot more details. – Shafik Yaghmour Nov 21 '18 at 04:03

8 Answers8

33

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.

Note that nowhere in mathematics it is defined that 1 / 0 = infinity. One might interpret it that way, but it is a personal, "shortcut" style interpretation, rather than a sound fact.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 1
    Agreed. `1 / 0;` and similar expressions in no way involve the macro `INFINITY` (unless by chance the implementation voluntarily chooses to use that to resolve the undefined behavior). – Matthew Flaschen Jun 09 '10 at 08:29
  • @Matthew: regarding your parenthesized comment: my findings show that this is indeed the way that many (most?) implementations choose to resolve this. Not to say that makes it implementation defined behavior, but it *does* add to the confusion. – SiegeX Jun 09 '10 at 08:43
  • Not with GCC and friends. I ran `#include int div_0_i = 1 / 0; float div_0_f = 1.0f / 0.0f; float my_inf = INFINITY;` through GNU cpp, and got `int div_0_i = 1 / 0; float div_0_f = 1.0f / 0.0f; float my_inf = (__builtin_inff());` So I don't see a connection. – Matthew Flaschen Jun 09 '10 at 08:49
  • @Matthew: Apparently gcc is not smart enough to replace div zero at pre-processor time but compile and run this code and you'll see what I mean. --> `#include float f = 1.0f / 0.0f; if(f == INFINITY) puts("f == INFINITY");` – SiegeX Jun 09 '10 at 16:58
  • @SiegeX, note that - as @Kenny pointed out in his answer - this may well simply be used as a signal of "overflow", aka "invalid value", not a computation result per se. – Péter Török Jun 09 '10 at 20:19
  • @PéterTörök, so in mathematics what's the answer to 1/0 ? – Pacerier Sep 22 '13 at 17:30
  • Wow... What does mathematics have to do with the language definition? What happens to das computar when das program sez `int x = 1 / 0;`? Does the computer pick daises? Or (as on almost every platform I've heard of) do we crash and burn really hard? The answer to `what is 1 / 0?` may be undefined, but **abnormal program termination** and **exception** are not undefined. Is the standard really *still* this loose? –  Apr 14 '14 at 21:22
  • Not only are the standards are appallingly loose, but the interpretation has gotten looser within the last few years. It used to be that in cases where a platform would naturally exhibit a certain behavior in cases not mandated by the standard, compilers would allow programmers to make use of it. Hyper-modern compiler philosophy, however, suggests that when given a program that would require such features to satisfy requirements when given certain inputs, it's better for a compiler to produce a smaller executable that will obey the C standard in all cases specified thereby... – supercat Jun 09 '15 at 23:11
  • ...than a larger executable that would satisfy requirements even in cases not mandated by the C standard. – supercat Jun 09 '15 at 23:12
  • @Pacerier in Mathematics it all depends what you call divide, and what you call zero. – floribon Sep 19 '15 at 00:53
  • "Note that nowhere in mathematics it is defined that 1 / 0 = infinity". Actually (nitpick alert), when working with the [extended real number line](https://en.wikipedia.org/wiki/Extended_real_number_line), it is possible to define just that, depending on context. But that's a special case. – sleske Feb 17 '22 at 07:14
16

1 / 0 is not infinity, only

lim 1/x = ∞ (x -> +0)
František Žiačik
  • 7,511
  • 1
  • 34
  • 59
  • 5
    this answer is not programming related. – Pete Kirkham Jun 09 '10 at 08:25
  • 24
    ... it's a perfectly valid answer given the question. – Peter Alexander Jun 09 '10 at 08:29
  • 10
    This is incorrect, it's only true if x is limited to positive values. – interjay Jun 09 '10 at 08:31
  • @interjay: you're right, i should have put there |lim 1/x| but the point is still there isnt it :) – František Žiačik Jun 09 '10 at 08:41
  • 5
    @Pete Alexander the question is "Division by zero: Undefined Behavior or Implementation Defined in C and/or C++ ?", not whether the behaviour in the standards agrees with the mathematical concept. The standard uses HUGE_VAL for such limits, which is the same bit pattern as infinity in IEE745 implementations. – Pete Kirkham Jun 09 '10 at 09:03
  • 2
    @Pete Kirkham: Well, there was the standard stated which answers the question, and another standard which wasn't contradictory to the first one and the contradiction was only assumed because of the wrong mathematical presumption, so in my opinion refusing this presumption makes the answer clear. – František Žiačik Jun 09 '10 at 09:20
  • There is no representation of exact zero in most floating point implementations. At least in IEE fp, there are both +0.0, and -0.0 which represent the range either size from exact zero to half the least representable value - all bits are zero, or all zeros with the sign bit set. Do not presume that 0.0 in C means exact zero in maths, or that maths prescribes its behaviour. Try adding one to INT_MAX and see if the interpreting the symbols as though maths worked gives the correct behaviour. – Pete Kirkham Jun 09 '10 at 12:07
  • 1
    The point being that you should answer questions based on standards with reference to the standards, not with reference to how things should work if the symbols in the code were interpreted in a different environment. It's no more correct to say 1.0/0.0 is undefined in maths so it is undefined in C99 than it is to say garbage is collected on Thursdays on my street, so garbage is only collected on Thursdays in Java. – Pete Kirkham Jun 09 '10 at 12:10
  • Yes, I should probably said what you say - that the author of the question should not mismatch maths to standards, but again, the author did it and based on that he thought that the standards are contradictory which is not true. Also, there are plenty of situations where maths is applicable (including this one). – František Žiačik Jun 09 '10 at 12:28
  • @František Žiačik , I think the fix can be as simple as changing to (note the plus sign), "x -> 0+". The absolute value of a quantity that does not exist doesn't make much sense. Rather, you want to use the definitional notation that gives a defined value (where +infinity has been defined). – Jose_X Sep 26 '14 at 15:25
  • @Pete Kirkham "The point being that you should answer questions based on standards with reference to the standards, not with reference to how things should work if the symbols in the code were interpreted in a different environment." That is what I was thinking; however, the standard does say "The result of the / operator is the quotient from the division of the first operand by the second". Thus C99, absent a listing of exceptions or clarification/redefinitions does invoke the usual meanings in mathematics as the correct C99 behavior. – Jose_X Sep 26 '14 at 15:29
  • On a projective space and on the Riemann sphere 1/0 and the limit are both nicely defined. – jinawee Sep 19 '18 at 14:12
11

This was not a math purest question, but a C/C++ question.

  • 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

The FPU will have a status flag that you can set to generate an exception if so desired, but this is not the norm.

INF can be quite useful to avoiding branching when INF is a useful result. See discussion here

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

wcochran
  • 10,089
  • 6
  • 61
  • 69
4

Why would it?

That doesn't make sense mathematically, it's not as if 1/x is defined as ∞ in mathematics in general. Also, you would at least need two more cases: -1/x and 0/x can't also equal ∞.

See division by zero in general, and the section about computer arithmetic in particular.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • I would contend that `y = 1/x` *does* equal ∞ as x --> 0 – SiegeX Jun 09 '10 at 08:25
  • 3
    This is an incredibly common mistake (I'm guessing that people who never actually took a formal calculus course are more likely to make it.) SiegeX, C/C++ doesn't have the concept of "`-->`" – shoosh Jun 09 '10 at 08:26
  • @shoosh: are you saying that the `lim [x --> +0] f(y) != ∞` where `f(y) = 1/x` ? – SiegeX Jun 09 '10 at 08:30
  • 1
    @shoosh: sure it does, haven't you seen this SO question http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator? =P – SiegeX Jun 09 '10 at 08:32
  • 1
    @SiegeX: I would contend that division by zero is undefined in maths.y = 1/x tends to infinity if x is positive and tends to 0. However, it tends to -infinity if x is negative and tends to 0. Which one do you choose? The answer is neither since division is defined mathematically in terms of multiplication i.e. d = p/q is defined as the number which multiplied by q gives p and no number times 0 can give anything but 0. – JeremyP Jun 09 '10 at 08:48
3

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.

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.

supercat
  • 77,689
  • 9
  • 166
  • 211
1

I've only got the C99 draft. In §7.12/4 it says:

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.

Note that INFINITY can be defined in terms of floating-point overflow, not necessarily divide-by-zero.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
1

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)

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

king_nak
  • 11,313
  • 33
  • 58
0

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".


[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 document and observe the rules it chose."

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".

[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"

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 ..] "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"

Documentation is a requirement for implementation-defined behavior.

Jose_X
  • 1,064
  • 8
  • 12
  • If an implementation defines `__STDC_IEC_559__`, it must implement divide-by-zero semantics consistent with that standard even though the C Standard would not *otherwise* impose any behavioral requirements. – supercat Jul 20 '16 at 19:42