我想计算(1.0-p)^n
,其中p是0和1之间的双精度数(通常非常接近0),n是一个正整数,可能是数百或数千(可能更大;我还不确定)。如果可能的话,我想只使用Java内置的java.lang.Math.pow(1.0-p, n)
来实现这一点,但我有点担心,这样做可能会对我感兴趣的值的范围造成巨大的准确性/精度损失。有人知道使用Java实现可能会出现什么样的错误吗?我不确定在它们的实现中发生了什么(日志和/或泰勒近似?),所以我不能冒险猜测。
我最关心的是相对误差(即不超过一个数量级)。如果答案是Java的实现会产生太多错误,那么您有什么好的库建议(但是,我希望不需要这个)?谢谢。
根据API文档:
计算结果必须在精确结果的1倍以内。
所以我认为你不需要担心实现,而需要担心浮点精度的限制。如果您最关心的是准确性而不是性能,则可以考虑使用BigDecimal.pow()
。
您可以查看一下java.land.Math类源文件,看看您是否能够理解确切的方法。这是链接,http://www.docjar.com/html/api/java/lang/Math.java.html。
一些实证结果:
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可能有足够的精度。