Операция с делением, приводящая к выполнению ошибки из-за SIGFPE, арифметическое исключение - PullRequest
0 голосов
/ 08 апреля 2019

Я написал алгоритм для MCU, который выполняет выражение двух параллельных сопротивлений перед выполнением дополнительных вычислений с результатом деления.При отладке значения не имели смысла;они были слишком большими и float var не обновлял их начальное значение.

Итак, я перешел к https://www.onlinegdb.com/ и попробовал часть своего алгоритма там.При выполнении кода он запускает нестандартный выход с арифметическим исключением в строке:

a = 1/(1/10 + 1/b) + 0.15; 

Сначала я работал с float, но я думал, что исключение может быть вызвано переполнением, поэтому я сделал переменнуюпамяти больше, используя double, но появляется то же исключение.Затем я попытался сделать то же самое, но сказал:

a = (1/10 + 1/b) + 0.15;

и исполнение сработало!

Итак, я видел, что причиной был оператор '1'.Но я не совсем понимаю, почему и как это исправить (без использования math.h).

Код такой:

#include <stdio.h>

float a = 0.0;
int b = 100;

int main()
{
    a = 1/(1/10 + 1/b) + 0.15;//Req 
    b = a; //get int part
    a *= 10;//fractionary part converted to dec
    if ((a - b*10)>5) b++;

    printf("float: %f , int: %i",a,b);

    return 0;
}

Я ожидал получить (отладка):

  • a = 1 / (1/10 + 1/100) = 9.09

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

Как работать со значениями типа float / double и int, чтобы избежать исключений, когда 1 / (что-то меньшее)?

Ответы [ 2 ]

3 голосов
/ 08 апреля 2019

Оба 1/10 и 1/b являются целыми числами выражениями, которые оба приводят к целому числу 0.

Итак, у вас простое деление на ноль ошибок.

Решите, используя, например, 1.0f как дивиденд, как 1.0f / (0.1f + 1.0f / b) + 0.15f.

1 голос
/ 08 апреля 2019

Это:

 a = 1/(1/10 + 1/b) + 0.15;//Req 

выполняет целочисленное деление в первой части, поскольку 1 и 10 имеют тип int.Вы имели в виду:

a = 1.f / (0.1f + 1.f / b) + 0.15f;

, особенно для встроенных целей, может быть очень важно убедиться, что ваши литералы равны float с, а не double с, поскольку поддержка может быть различной.

...