gpt4 book ai didi

java - BigDecimal 下溢错误的可能解决方案

转载 作者:行者123 更新时间:2023-11-30 02:42:13 28 4
gpt4 key购买 nike

我正在尝试使用BigDecimal.pow(int i)具有非常大的基数和指数,但是我得到 ArithmeticException: Underflow错误。

简单来说,代码是:

BigDecimal base = BigDecimal.valueOf(2147483645.4141948);
BigDecimal product = base.pow(987654321);

System.out.println("product = " + product.toPlainString());

是的,这是一个欧拉计划问题。但我知道我的数字是正确的。这不是一个数学问题,纯粹是我不明白为什么BigDecimal.pow(int i)给了我一个ArithmeticException: Underflow .

我知道BigDecimal scale is a 32-bit int 但有什么办法可以绕过这个并计算这么大的值吗?如果有帮助,我确实计划对产品进行铺底并通过 100000000 进行修改。因为我只想要最后 8 位数字。如果有任何其他方法可以在数学上完成此操作,我需要提示。

堆栈跟踪:

Exception in thread "main" java.lang.ArithmeticException: Underflow
at java.math.BigDecimal.checkScale(BigDecimal.java:3841)
at java.math.BigDecimal.pow(BigDecimal.java:2013)
at test.main(test.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1

谢谢。

最佳答案

答案是一个十进制数,有 6913580247 位小数,以“11234048”(最后 8 位小数)结尾。您的基数有 7 位小数,987654321 * 7 等于 6913580247。

我的问题是这个数字无法用 BigDecimal 表示,因为它需要 6913580247 的小数位数,这会溢出 BigDecimal 用于其小数位数的整数。我不知道您想要哪种格式的号码。以下代码打印结果为

Result is 1.1234048e-6913580240

也就是说,就像科学记数法一样,只是指数超出了科学记数法的正常范围。对于模 100000000 我正在使用:

public static final BigDecimal moduloBase = new BigDecimal(10).pow(8); // 8 digits

现在我做到了:

    long noOfDecimals = 987654321L * 7L;

BigDecimal bd = new BigDecimal("54141948"); // last 8 digits of base
bd = bd.pow(379721);
bd = bd.remainder(moduloBase);
bd = bd.pow(2601);
bd = bd.remainder(moduloBase);

double result = bd.doubleValue() / 10_000_000.0; // print with 7 decimals
System.out.println("Result is " + result + "e" + (-(noOfDecimals - 7)));

我正在使用 Anton Dovzhenko 的答案中的技巧,事实上 987654321 是 2601 * 379721。计算在我的计算机上需要大约 4 秒,这可能会有很大差异。

期待您的后续问题。

编辑:计算的核心部分可以使用 BigInteger 而不是 BigDecimal 通过更简单的代码和更快的速度完成:

    BigInteger bi = new BigInteger("54141948");
bi = bi.modPow(new BigInteger("987654321"), new BigInteger("100000000"));
System.out.println("As BigInteger: " + bi);

(它会打印 11234048,正如我们现在所知道的那样。)

关于java - BigDecimal 下溢错误的可能解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41309752/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com