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

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

Поэтому я зашел на 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/(что-то меньшее)?


person Suvi_Eu    schedule 08.04.2019    source источник


Ответы (2)


И 1/10, и 1/b являются целочисленными выражениями, результатом которых является целое число 0.

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

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

person Some programmer dude    schedule 08.04.2019
comment
У вас есть причина использовать #include ‹stdio.h› double a = 0.0; интервал б = 100; int main() { a = 1,0/(1,0/10,0 + 1/(float)b) + 0,15; б = а; а *= 10; если ((a - b*10)›5) b++; printf(float: %f , int: %i,a,b); вернуть 0; } фиксированный. Спасибо. - person Suvi_Eu; 08.04.2019

Этот:

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

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

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

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

person unwind    schedule 08.04.2019