Moshe
Moshe

Reputation: 225

Simple question about 'floating point exception' in C

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

Answers (7)

wnoise
wnoise

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

RiaD
RiaD

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

Alnitak
Alnitak

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

user195488
user195488

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

Joe
Joe

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

Jeremy Roman
Jeremy Roman

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

JonH
JonH

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

Related Questions