views:

308

answers:

5

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.

+3  A: 

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
I would contend that `y = 1/x` *does* equal ∞ as x --> 0
SiegeX
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
@shoosh: are you saying that the `lim [x --> +0] f(y) != ∞` where `f(y) = 1/x` ?
SiegeX
@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
@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
+7  A: 

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
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
@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
Not with GCC and friends. I ran `#include <math.h> 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
@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 <math.h> float f = 1.0f / 0.0f; if(f == INFINITY) puts("f == INFINITY");`
SiegeX
@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
+4  A: 

1 / 0 is not infinity, only

lim 1/x = ∞ (x -> 0)

František Žiačik
this answer is not programming related.
Pete Kirkham
... it's a perfectly valid answer given the question.
Peter Alexander
This is incorrect, it's only true if x is limited to positive values.
interjay
@interjay: you're right, i should have put there |lim 1/x| but the point is still there isnt it :)
František Žiačik
@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
@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
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
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
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
A: 
KennyTM
+1  A: 

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