Неправильный подсчет long double
Имеется вот такой код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
long double s21_atofLong(const char *str) {
long int length = strlen(str);
long double returnValue = 0;
int counterE = 0;
int sign = 1;
int i = 0;
if ((str[i] == 'i' || str[i] == 'I')
&& (str[i + 1] == 'n' || str[i + 1] == 'N')
&& (str[i + 2] == 'f' || str[i + 2] == 'F')) {
returnValue = INFINITY;
}
if ((str[i] == 'N' || str[i] == 'n')
&& (str[i + 1] == 'a' || str[i + 1] == 'A')
&& (str[i + 2] == 'N' || str[i + 2] == 'n')) {
returnValue = NAN;
}
if (str[i] == '+' || str[i] == '-') {
if (str[i] == '-') {
sign = -1;
}
i++;
}
while(str[i] >= '0' && str[i] <= '9') {
returnValue = returnValue * 10 + (str[i] - 48);
i++;
}
if (str[i] == '.') {
i++;
}
int pow1 = 1;
while(str[i] >= '0' && str[i] <= '9') {
returnValue = returnValue + (str[i] - 48.0) / (10 * pow1);
i++;
pow1 = pow1 * 10;
}
if (str[i] == 'e') {
i++;
}
int signE = 1;
if (str[i] == '+' || str[i] == '-') {
if (str[i] == '-') {
signE = -1;
}
i++;
}
while(str[i] >= '0' && str[i] <= '9') {
counterE = counterE * 10 + (str[i] - 48);
i++;
}
returnValue = returnValue * pow(10, signE * counterE);
return sign * returnValue;
}
int main(int argc, char **argv) {
long double a1 = 1, a2 = 1;
const char str[] = "53.123";
const char fstr[] = "%Lf";
a1 = s21_atofLong(str);
sscanf(str, fstr, &a2);
printf("%.25Lf %.25Lf", a1, a2);
return 0;
}
Почему из sscanf я получаю немного другое значение, а не как в своей функции?
53.1230000000000000051625371
53.1230000000000000016930901
Ну и получается что при сравнении значений с максимальной точностью получаю, что они не равны. Как правильно будет посчитать?
Ответы (1 шт):
Дробное число невозможно задать точно потому что размер переменной не бесконечен. На каждом шаге оно будет округляться до ближайшего двоичнозадаваемого числа. Разное количество операций приводит к разному округлению.
Сравнивать числа с фиксированной и с плавающей точкой можно только через выражения вроде abs(a-b) < 0.0000000001. Значение подбирается исходя из оценки максимальной погрешности и требованиям к точности.
Обычно это значение зависит от погрешности вводимых данных. Минимальное значение должно быть в 2 раза больше максимальной погрешности косвенных измерений.