Reputation: 225
I have the following C program:
#include <stdio.h>
int main()
{
double x=0;
double y=0/x;
if (y==1)
printf("y=1\n");
else
printf("y=%f\n",y);
if (y!=1)
printf("y!=1\n");
else
printf("y=%f\n",y);
return 0;
}
The output I get is
y=nan
y!=1
But when I change the line double x=0; to int x=0; the output becomes
Floating point exception
Can anyone explain why?
Upvotes: 1
Views: 4810
Reputation: 9932
Floating point is inherently modeling the reals to limited precision. There are only a finite number of bit-patterns, but an infinite (continuous!) number of reals. It does its best of course, returning the closest representable real to the exact inputs it is given. Answers that are too small to be directly represented are instead represented by zero. Dividing by zero is an error in the real numbers. In floating point, however, because zero can arise from these very small answers, it can be useful to consider x/0.0 (for positive x) to be "positive infinity" or "too big to be represented". This is no longer useful for x = 0.0.
The best we could say is that dividing zero by zero is really "dividing something small that can't be told apart from zero by something small that can't be told apart from zero". What the answer to this? Well, there is no answer for the exact case of 0/0, and there is no good way of treating it inexactly. It would depend on the relative magnitudes, and so the processor basically shrugs and says "I lost all precision -- any result I gave you would be misleading", by returning Not a Number.
In contrast, when doing an integer divide by zero, the divisor really can only mean precisely zero. There's no possible way to give a consistent meaning to it, so when your code asks for the answer, it really is doing something illegitimate.
(It's an integer division in the second case, but not the first because of the promotion rules of C. 0 can be taken as an integer literal, and as both sides are integers, the division is integer division. In the first case, the fact that x
is a double causes the dividend to be promoted to double. If you replace the 0
by 0.0
, it will be a floating-point division, no matter the type of x
.)
Upvotes: -1
Reputation: 47620
If you divide int
to int
you can divide by 0.
0/0
in doubles is NaN
.
int x=0;
double y=0/x; //0/0 as ints **after that** casted to double. You can use
double z=0.0/x; //or
double t=0/(double)x; // to avoid exception and get NaN
Upvotes: 0
Reputation: 339836
There's a special bit-pattern in IEE754 which indicates NaN
as the result of floating point division by zero errors.
However there's no such representation when using integer arithmetic, so the system has to throw an exception instead of returning NaN
.
Upvotes: 0
Reputation:
Because due to IEEE 754, NaN will be produced when conducting an illegal operation on floating point numbers (e.g. 0/0
, ∞×0
, or sqrt(−1)
).
There are actually two kinds of NaNs, signaling and quiet. Using a signaling NaN in any arithmetic operation (including numerical comparisons) will cause an "invalid" exception. Using a quiet NaN merely causes the result to be NaN too.
The representation of NaNs specified by the standard has some unspecified bits that could be used to encode the type of error; but there is no standard for that encoding. In theory, signaling NaNs could be used by a runtime system to extend the floating-point numbers with other special values, without slowing down the computations with ordinary values. Such extensions do not seem to be common, though.
Also, Wikipedia says this about integer division by zero:
Integer division by zero is usually handled differently from floating point since there is no integer representation for the result. Some processors generate an exception when an attempt is made to divide an integer by zero, although others will simply continue and generate an incorrect result for the division. The result depends on how division is implemented, and can either be zero, or sometimes the largest possible integer.
Upvotes: 1
Reputation: 57179
Integer division by 0 is illegal and is not handled. Float values on the other hand are handled in C
using NaN. The following how ever would work.
int x=0;
double y = 0.0 / x;
Upvotes: 0
Reputation: 16355
You're causing the division 0/0
with integer arithmetic (which is invalid, and produces the exception you see). Regardless of the type of y
, what's evaluated first is 0/x
.
When x
is declared to be a double
, the zero is converted to a double
as well, and the operation is performed using floating-point arithmetic.
When x
is declared to be an int
, you are dividing one int
0 by another, and the result is not valid.
Upvotes: 2
Reputation: 33153
Check the min and max values of an integer data type. You will see that an undefined or nan result is not in it's range.
And read this what every computer scientist should know about floating point.
Upvotes: 0