Почему в этой программе есть исключение с плавающей точкой? - PullRequest
1 голос
/ 08 февраля 2020
#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);
  }
}

Я не понимаю, почему я сталкиваюсь с ошибкой исключения с плавающей запятой в этой программе.

Ответы [ 3 ]

7 голосов
/ 08 февраля 2020
for(i = 0; i < 30; i++){
    c = (a[i] + i)/(i-1);

На второй итерации этого l oop вы делите на ноль.

По историческим причинам в Unix системах целочисленное деление на ноль сообщается с использованием того же сигнала (SIGFPE, " Исключение с плавающей точкой "), которое используется для сообщения об ошибках, фактически вызванных арифметикой с плавающей точкой c. Это нельзя изменить сейчас, потому что от этого зависит слишком много существующих программ.

(Я не знаю, каковы были исторические причины. Они, вероятно, являются чем-то вроде "PDP-11) инструкция деления с плавающей запятой, но не целочисленная, поэтому оригинальный компилятор C использовал математическое вычисление с плавающей запятой для реализации целочисленного деления ", но я просто придумал это, если это правда, это случайно.)

( По иронии судьбы, на современном процессоре деление на ноль с плавающей точкой обычно дает результат ± Inf, но не запускает сигнал, если только вы не используете fesetenv для включения захвата.)

1 голос
/ 08 февраля 2020

Во второй итерации l oop, i равно 1, поэтому при делении на i-1 вы делитесь на 0.

То, как это будет исправлено, будет зависеть от цель вашей программы.

0 голосов
/ 08 февраля 2020

На второй итерации i = 1, поэтому вы делите на 0.

...