Я использую MPIR для работы с очень маленькими числами. Почему-то ответы, которые я получаю, неверны, и я понятия не имею, почему (что-то с округлением, я думаю …). Как округление работает в MPIR и является ли причиной того, что я получаю неправильные ответы?
Вот код (соответствующая часть):
long long a = 100000;
mpf_class calc(p[i],500);
cout << "p[i] = " << setprecision(32) << calc << endl;
calc = 1-calc;
cout << "1-p[i] = " << setprecision(32) << calc << endl;
mpf_pow_ui(calc.get_mpf_t(), calc.get_mpf_t(), a);
cout << "(1-p[i])^a = " << setprecision(32) << calc << endl;
cout << "probLessThanR = " << setprecision(32) << probLessThanR << endl;
calc = 1-calc-probLessThanR;
cout << "1-(1-p[i])^a-probLessThanR = " << setprecision(32) << calc << endl;
if (calc>0)
cout << "calc>0 = " << 1 << endl;
И вот вывод для некоторых значений p [i] и probLessThanR:
p[i] = 2.0432284241450287639483056612667e-17
1-p[i] = 0.99999999999999997956771575854971
(1-p[i])^a = 0.99999999999795677157585705860637
probLessThanR = 2.0432284241428158e-012
1-(1-p[i])^a-probLessThanR = 1.2561170838194078535224341399684e-25
calc>0 = 1
p[i] = 2.1679268932387850003127872242701e-17
1-p[i] = 0.99999999999999997832073106761215
(1-p[i])^a = 0.99999999999783207310676356492969
probLessThanR = 2.1679268932410045e-012
1-(1-p[i])^a-probLessThanR = -4.5694136331284619232701251208227e-24
p[i] = 2.2996656655640389938724454087815e-17
1-p[i] = 0.99999999999999997700334334435961
(1-p[i])^a = 0.99999999999770033433443860521077
probLessThanR = 2.2996656655715272e-012
1-(1-p[i])^a-probLessThanR = -1.0132363051975571461595673730287e-23
p[i] = 2.4388090428503683876184122197242e-17
1-p[i] = 0.99999999999999997561190957149632
(1-p[i])^a = 0.99999999999756119095715260547742
probLessThanR = 2.4388090428370166e-012
1-(1-p[i])^a-probLessThanR = 1.0377918963850787511442329601381e-23
calc>0 = 1
Все ответы 1-(1-p[i])^a-probLessThanR
должен быть положительным. Я предпочитаю положительный и менее точный, чем отрицательный (но точность действительно важна).
Есть идеи?
Изменить: добавлен вывод в виде текста и значение. Кстати, a long long по причине (он может иметь большие значения).
Нет, это правильно.
Спасибо так много за скриншот. Гораздо более художественный, чем простой крой & вставить. Кто заботится о юзабилити в конце концов?
Если (1-p[I])^a
является 0.99999999999783207310676356492969
А также probLessThanR
является 2.1679268932410045e-12
затем probLessThanR
является 0.0000000000021679268932410045
Таким образом, используя дополнение начальной школы с переносом:
(1-p[I])^a + probLessThanR
это здесь
0.99999999999783207310676356492969
+ 0.0000000000021679268932410045`
~ 0.9999999999999999999999045684...
Carry 1 1
= 1.0000000000000000000000045694...
Так 1-(1-p[I])^a - probLessThanR
является 0.0000000000000000000000045694...
, Что у тебя есть.
Других решений пока нет …