我试图获得double
值的幂,其中指数非常大(Java BigInteger
可以包含它(指数),例如:10 ^ 30)
也就是说,我希望找到类似 1.75 ^(10 ^ 30)或 1.23 ^(34234534534222)的内容。如果输出太大,请通过获取来修改它由10 ^ 9 + 7的素数模数。
如果我想找到Integer
的强大功能,我可以使用 BigInteger.modPow()
方法来获取BigInteger
个参数:
( BigInteger modPow(BigInteger exponent, BigInteger m) )
据我所知,这就是我用Java获得的东西
new BigDecimal("1.5").pow(1000); // .pow() can get only integers as a parameter , but i want to pass a big number like a BigInteger
我无法在java中为 BigDecimal
找到相应的( BigInteger.modPow())
,或者我错过了。
有没有办法做到这一点 - 计算一个浮点数的大功率(Decimal
)?
输入和输出示例:
输入:num //或1.5或任何十进制数。也可以是整数。
exponent:exp //大整数或长值
输出:num ^ exp // num to ther power exp
即计算 1.23 ^(34234534534222)
如果输出太大,则通过将模数设为10 ^ 9 + 7
的素数来修改它答案 0 :(得分:1)
有Math.BigDecimal implementation of core mathematical functions有:
static java.math.BigDecimal powRound(java.math.BigDecimal x, java.math.BigInteger n)
Raise to an integer power and round.
这似乎正是你所需要的。有一个外部库的事实表明在java.Math
中没有像这样的方法的核心实现。
作为旁注,我可以说,如果您的输入在小数位方面相当小(因此不合理),就像1.5一样,您可以在15/10进行转换并执行
(15^BigInteger)/(10^BigInteger)
modPow(BigInteger exponent, BigInteger m)
BigInteger
。这显然提高了计算的复杂性和数量。
答案 1 :(得分:0)
有几点需要注意。正如GáborBakos指出的那样,结果值很可能包含太多数字,甚至可以表示为BigDecimal
。
此外,这些数字的数字增长很快,因此计算类似2.0 34234534534222 的内容在存储方面完全超出范围(并且,正如我所假设的,就所需时间而言)。
你提到当值变得“太大”时,可以以大质数为模来计算该值。虽然你没有说明这意味着什么,但这不一定对你有帮助,因为使用modulo不会截断小数位。你必须以某种方式限制计算发生的精度。
但是,使用exponentiation by squaring的最简单实现可能粗略如下所示:
import java.math.BigDecimal;
import java.math.BigInteger;
public class BigDecimalPow {
public static void main(String[] args) {
BigDecimal b = new BigDecimal(1.5);
BigInteger e = new BigInteger("325322");
BigDecimal result = pow(b, e);
System.out.println("Done "+result.scale());
System.out.println(result);
}
/**
* Computes d to the power of e
* @param b The value
* @param e The exponent
* @return The power
*/
private static BigDecimal pow(BigDecimal b, BigInteger e) {
BigDecimal result = BigDecimal.ONE;
BigDecimal p = b;
int skipped = 0;
while (e.compareTo(BigInteger.ZERO) > 0) {
if (e.and(BigInteger.ONE).equals(BigInteger.ONE)) {
if (skipped > 0) {
if (skipped > 29) {
p = pow(p, BigInteger.ONE.shiftLeft(skipped));
} else {
p = p.pow(1 << skipped);
}
skipped = 0;
}
result = result.multiply(p);
}
skipped++;
e = e.shiftRight(1);
System.out.println(e);
}
return result;
}
}
注意:上面的实现真的简单。最有可能的解决方案对某些情况更有效,或者使用模运算来支持“更大”的数字。但是你根本不能代表(可能)34234534534222小数位,除非你有34 TB的RAM和一个long
寻址的JVM,所以我怀疑会有一个解决方案满足你直到现在所说的要求 - 但是如果有人证明我错了,那就会投票+赏金......