对于大 n,java.lang.Math.pow(x, n) 的准确/精确度如何?

发布于 2024-10-30 18:24:59 字数 347 浏览 0 评论 0原文

我想计算 (1.0-p)^n 其中 p 是 0 到 1 之间的双精度数(通常非常接近 0),n 是一个正整数,可能约为数百或数千(也许更大;我还不确定)。如果可能的话,我希望仅使用 Java 内置的 java.lang.Math.pow(1.0-p, n) 来实现此目的,但我有点担心可能会严重损失准确性/精确地用我感兴趣的值的范围来这样做。有人粗略地知道我使用Java的实现可能会出现什么样的错误吗?我不确定他们的实现中到底发生了什么(日志和/或泰勒近似?),所以我不能冒险一个好的猜测。

我最关心的是相对误差(即偏差不超过一个数量级)。如果答案是 Java 的实现会产生太多错误,您是否有任何好的库推荐(但我再次希望这不需要)?谢谢。

I would like to calculate (1.0-p)^n where p is a double between 0 and 1 (often very close to 0) and n is a positive integer that might be on the order of hundreds or thousands (perhaps larger; I'm not sure yet). If possible I would love to just use Java's built in java.lang.Math.pow(1.0-p, n) for this, but I'm slightly concerned that there might be a gigantic loss of accuracy/precision in doing so with the range of values that I'm interested in. Does anybody have a rough idea of what kind of error I might expect using Java's implementation? I'm not sure what goes on under the hood in their implementation (logs and/or Taylor approximations?), so I can't hazard a good guess.

I'm mostly concerned about relative error (i.e. not being off by more than an order of magnitude). If the answer turns out to be that Java's implementation will produce too much error, do you have any good library recommendations (but again, I'm hoping this shouldn't be needed)? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情稳全场 2024-11-06 18:24:59

根据API文档:

计算结果必须与准确结果的误差在 1 ulp 以内。

因此,我认为您不需要担心实现,而需要担心浮点精度的限制。如果您最关心的是准确性而不是性能,您可能需要考虑使用 BigDecimal.pow()。

According to the API doc:

The computed result must be within 1 ulp of the exact result.

So I don't think you need to worry about the implementation so much as about the limits of floating-point accuracy. You may want to consider using BigDecimal.pow() if accuracy rather than performance is your primary concern.

少女净妖师 2024-11-06 18:24:59

你可以看一下java.land.Math类源文件,看看你是否能理解确切的方法。这是链接, http://www.docjar.com/ html/api/java/lang/Math.java.html

You can take a look at the java.land.Math class source file and see if you can understand the exact method. Here is the link, http://www.docjar.com/html/api/java/lang/Math.java.html.

梦旅人picnic 2024-11-06 18:24:59

一些经验结果:

public static void main(String[] args)
{
    double e = 0.000000000001d;
    System.out.println(Math.pow(1-e, 1.0d/e));
    float f =  0.000001f;
    System.out.println(Math.pow(1-f, 1.0f/f));
}

0.36788757938730976
0.3630264891374932

两者都应该收敛到 1/e (0.36787944....),所以显然 float 是不可能的,但 double 可能对你来说有足够的精度。

Some empirical results:

public static void main(String[] args)
{
    double e = 0.000000000001d;
    System.out.println(Math.pow(1-e, 1.0d/e));
    float f =  0.000001f;
    System.out.println(Math.pow(1-f, 1.0f/f));
}

0.36788757938730976
0.3630264891374932

Both should converge to 1/e (0.36787944....) so obviously float is out of the question but double might have enough precision for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文