Получаемые результаты соответствуют 32-битной арифметике. Не зная больше о вашей среде, невозможно посоветовать, что делать.
Если предположить, что показанный код работает, то есть вы ничего не конвертируете в строки или числа с плавающей запятой, то в C ++ нет исправления. Это за пределами кода, который вы показали, и зависит от среды.
Когда Патрик Макдональд и Треб повысили точность ваших входных данных и ошибку на a-c
, я подумал, что на это взгляну. Одним из методов рассмотрения ошибок округления является интервальная арифметика, которая устанавливает верхнюю и нижнюю границы, значение которых представляет явное (они неявны в числах с плавающей запятой и фиксируются с точностью представления). Обрабатывая каждое значение как верхнюю и нижнюю границы и расширяя границы на ошибку в представлении (приблизительно x * 2 ^ -53 для двойного значения x), вы получаете результат, который дает нижнюю и верхнюю границы для точность значения с учетом ошибок точности худшего случая.
Например, если у вас есть значение в диапазоне [1.0, 2.0] и вычесть из него значение в диапазоне [0.0, 1.0], то результат должен лежать в диапазоне [ниже (0.0), выше ( 2.0)] как минимальный результат 1,0-1,0, а максимальный 2,0-0,0. below
и above
эквивалентны полу и потолку, но для следующего представимого значения, а не для целых чисел.
Использование интервалов, которые представляют наихудшее двойное округление:
getSlope(
a = [2.7115599999999995262:2.7115600000000004144],
b = [-1.6416099999999997916:-1.6416100000000002357],
c = [2.7041299999999997006:2.7041300000000005888],
d = [-1.7221899999999998876:-1.7221900000000003317])
(d-b) = [-0.080580000000000526206:-0.080579999999999665783]
(c-a) = [-0.0074300000000007129439:-0.0074299999999989383218]
to double precision [10.845222072677243474:10.845222072679954195]
Таким образом, хотя c-a
мало по сравнению с c
или a
, оно все равно велико по сравнению с двойным округлением, поэтому, если вы использовали наихудшее из возможных округление с двойной точностью, то вы могли бы доверять этому значению, чтобы быть точным до 12 цифр - 10,8452220727. Вы потеряли несколько цифр из-за двойной точности, но вы по-прежнему работаете не только со значением, которое вы вводите.
Но если бы входные данные были точны только до значащих цифр, то вместо того, чтобы быть двойным значением 2.71156 +/- eps, диапазон ввода был бы [2.711555,2.711565], поэтому вы получите результат:
getSlope(
a = [2.711555:2.711565],
b = [-1.641615:-1.641605],
c = [2.704125:2.704135],
d = [-1.722195:-1.722185])
(d-b) = [-0.08059:-0.08057]
(c-a) = [-0.00744:-0.00742]
to specified accuracy [10.82930108:10.86118598]
, что намного шире.
Но вам придется изо всех сил отследить точность вычислений, и ошибки округления, присущие с плавающей запятой, в этом примере незначительны - это точность до 12 цифр с наихудшим округлением с двойной точностью.
С другой стороны, если ваши входные данные известны только из 6 цифр, на самом деле не имеет значения, получите ли вы 10.8557 или 10.8452. Оба находятся в пределах [10.82930108: 10.86118598].