Насколько я понимаю, при вычитании двух чисел double
с двойной точностью в С ++ они сначала преобразуются в значащую величину, начиная с единицы, умноженной на 2, в степени экспоненты. Тогда можно получить ошибку, если вычитаемые числа имеют одинаковый показатель степени и много одинаковых цифр в мантиссе, что приведет к потере точности. Чтобы проверить это для своего кода, я написал следующую безопасную функцию сложения:
double Sadd(double d1, double d2, int& report, double prec) {
int exp1, exp2;
double man1=frexp(d1, &exp1), man2=frexp(d2, &exp2);
if(d1*d2<0) {
if(exp1==exp2) {
if(abs(man1+man2)<prec) {
cout << "Floating point error" << endl;
report=0;
}
}
}
return d1+d2;
}
Однако, проверяя это, я замечаю что-то странное: кажется, что фактическая ошибка (не то, сообщает ли функция об ошибке, а фактическая ошибка, полученная в результате вычисления), похоже, зависит от абсолютных значений вычтенных чисел, а не только от количества равных цифр. в значении ...
Например, используя 1e-11
в качестве точности prec
и вычитая следующие числа:
1) 9.8989898989898-9.8989898989897: функция сообщает об ошибке, и я получаю крайне неверное значение 9.9475983006414e-14
2) 98989898989898-98989898989897: функция сообщает об ошибке, но я получаю правильное значение 1
Очевидно, я что-то неправильно понял. Любые идеи?