1
#include <stdio.h>

int
main()
{
  int i;
  int c;
  int a[30] = { 5,  7,  11, 13,  17,  19,  23,  29,  31,  37,
                41, 43, 47, 53,  59,  61,  67,  71,  73,  79,
                83, 89, 97, 101, 103, 107, 109, 113, 127, 131 };
  for (i = 0; i < 30; i++) {
    c = (a[i] + i) / (i - 1);
    printf("Value of c is %d", c);
  }
}

I am not getting why I am facing floating point exception error in this program.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93

3 Answers3

8
for(i = 0; i < 30; i++){
    c = (a[i] + i)/(i-1);

On the second iteration of this loop you divide by zero.

For historical reasons, on Unix systems integer division by zero is reported using the same signal (SIGFPE, "Floating point exception") that is used to report errors actually caused by floating-point arithmetic. This can't be changed now because too many existing programs depend on it.

(I don't know what the historical reasons actually were. They're probably something along the lines of "the PDP-11 had a floating point divide instruction but not an integer divide instruction, so the original C compiler used floating point math to implement integer divide" but I just made that up, if it's true it's by accident.)

(Ironically, on a modern CPU floating-point division by zero will usually produce a ±Inf result but not trigger a signal, unless you use fesetenv to turn on trapping.)

zwol
  • 135,547
  • 38
  • 252
  • 361
  • "*historical reasons*" as there were? The usual "It's always been like this, so also it's wrong we stick to it." Or something else? Just curious. – alk Feb 08 '20 at 14:26
  • @alk I don't know the history. I know changing it now would be considered both an ABI and an API break - you'd have to introduce a whole new signal number because there's nothing else more appropriate. A three-argument signal handler for `SIGFPE` can use `si_code` to tell what actually happened but I didn't want to put that in my answer because I thought it would be too much of a digression. – zwol Feb 08 '20 at 14:27
  • @alk: I do not recall either, so I posted a [question](https://stackoverflow.com/questions/60127747/why-was-sigfpe-used-for-integer-arithmetic-exceptions). I have some vague recollection it might be hardware (Intel?) that generated one trap for all arithmetic exceptions. But why would one not then name the signal `SIGARITH` or something like that instead of `SIGFPE`? – Eric Postpischil Feb 08 '20 at 14:30
  • @EricPostpischil Thanks, if you get a good answer I'll summarize it in here. – zwol Feb 08 '20 at 14:33
  • 1
    @zwol: Changing it now could be done be defining `SIGARITH` to be the same value as `SIGFPE` and updating various text messages to report “arithmetic exception” instead of “floating-point exception,” for example. In other words, change nothing about how the software works except the text for humans. Alternately, we could define the integer types as a subset of floating-point types with an exponent range of zero to zero, thus making all integer exceptions floating-point exceptions. – Eric Postpischil Feb 08 '20 at 14:35
  • *"(Ironically, on a modern CPU floating-point division by zero will usually produce a NaN result but not trigger a signal, unless you use fesetenv to turn on trapping.)"* To be clear, dividing by zero in floting-point will result in +inf or -inf. Only dividing 0 by 0 will result in NaN. – DarkAtom Feb 08 '20 at 14:37
  • @EricPostpischil With my glibc contributor hat on, I'd be hesitant to introduce a new `SIG*` constant, _especially_ one that's another name for an existing one, because those never, ever go away and some programs (e.g. interpreters that let you handle signals from the interpreted language) have to know all of the names and which are aliases. Changing the strsignal() text for SIGFPE to "Arithmetic exception" might be doable though. – zwol Feb 08 '20 at 14:42
  • @DarkAtom: Other operations that produce NaN include multiplying a zero by an infinity, addition (or subtraction) of opposite (or like) signed infinities, division of infinities, remainder(x, y) with infinite x or zero y, and square root of numbers less than zero. – Eric Postpischil Feb 08 '20 at 14:43
1

In the second iteration of the loop, i is 1, so when you divide by i-1, you are dividing by 0.

How this would be fixed would depend on the purpose of your program.

GoodDeeds
  • 7,956
  • 5
  • 34
  • 61
0

At second iteration i = 1therefore you divide by 0.

Eraklon
  • 4,206
  • 2
  • 13
  • 29