Исключение с плавающей точкой Назначение читабельности CS50 - PullRequest
0 голосов
/ 24 апреля 2020

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

#include <stdio.h> 
#include <cs50.h> 
#include <ctype.h> 
#include <string.h>
#include <math.h>

int main(void)
{
    //promt user for text 
    string n = get_string("Text: ");
    int sumletters = 0; 
    int sumdots = 0;
    int sumspaces = 1;

    for (int i = 0; i < strlen (n); i++ )
    {
        if (n[i] >= 'A' && n[i] <= 'z')
        {
           sumletters = sumletters + 1; 
        }

        if (n[i] == ' ')
        {
            sumspaces = sumspaces + 1;
        }

        if (n[i] == '.' || n[i] == '?' || n[i] == '!' )
        {
            sumdots = sumdots + 1;   
        }

        float L = sumletters / (sumspaces / 100); 
        float S = sumdots / (sumspaces / 100); 
        int index = round ((0.0588 * L) - (0.296 * S) - 15.8); 

        if (index < 1)
        {
            printf ("Before grade 1\n");
        }
        {
            printf ("Grade 16+\n");
        }
        else 
        {
            printf ("Grade %i", index);
        }
    }
printf ("\n");
}

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Ниже приведено целочисленное деление, а частное часто равно нулю, так как int математика отбрасывает дробь.

int sumspaces;
...
sumspaces / 100

Ниже приведено int деление 0.

int sumletters;
...
//           v---------------v might be 0 
sumletters / (sumspaces / 100); 

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

По различным причинам общего обработчика ошибок, int деление на ноль может быть сообщенным как исключение с плавающей запятой.


Так как во многих операциях тип результата находится не в операции, а только в присваивании, такие проблемы являются общими.

Вместо этого застрахуйте математика использует тип назначения.

//                        v---------------v int division                       
// float L = sumletters / (sumspaces / 100); 

float L = sumletters / (sumspaces / 100.0f); 
//                     ^------------------^ At least float division                       

В стороне: Нет веских оснований для использования float типов здесь, просто используйте double.
Обратите внимание, что код использует double математика, а не float математика в:

//         v----v         v---v        v--v  double constants
   round ((0.0588 * L) - (0.296 * S) - 15.8)
// ^---^                                     double function
0 голосов
/ 24 апреля 2020

Это ошибочная часть:

sumletters / (sumspaces / 100)

sumspaces / 100 использует целочисленное деление, поэтому оно почти всегда будет 0. Вы можете реорганизовать свой код для использования деления с плавающей запятой, просто распределяя деление:

sumletters / sumspaces * 100
...