为什么小数的答案是错误的?与 MPIR

Why is the answer for small numbers wrong? with MPIR

本文关键字:错误 MPIR 小数 答案 为什么      更新时间:2023-10-16

我正在使用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. 顺便说一句,a 很长是有原因的(它可以有更大的值)。

不,没错。

非常感谢 您的屏幕截图。比单纯的剪切和粘贴更具艺术性。毕竟谁在乎可用性?

如果(1-p[I])^a 0.99999999999783207310676356492969

probLessThanR 2.1679268932410045e-12

那么probLessThanR0.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....这就是你所拥有的。