Почему неправильный ответ для небольших чисел? с MPIR

0

Я использую 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. BTW, a длинный длинный по причине (он может иметь большие значения).

  • 3
    Скопируйте и вставьте свой вывод вместо скриншота. Это довольно неприятно читать, некоторые люди могут не иметь включенных изображений и не могут быть использованы для цитирования (частей) вывода в возможных ответах.
  • 0
    Что такое вар а?
Показать ещё 2 комментария
Теги:
rounding
rounding-error

1 ответ

0
Лучший ответ

Нет, это правильно.

Большое спасибо за скриншот. Гораздо более художественный, чем просто вырезать и вставить. Кто заботится о юзабилити в конце концов?

Если (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... Это то, что у вас есть.

  • 0
    Ой про скриншот извини. А также теперь я понимаю, что мой вопрос был глупым. Я использовал калькулятор Google, чтобы проверить, каким должен быть реальный результат. Я никогда не буду делать это снова: \

Ещё вопросы

Сообщество Overcoder
Наверх
Меню