Giải pháp cho các đối số dưới 1.7976931348623157E308 (Double.MAX_VALUE) nhưng kết quả hỗ trợ với hàng triệu chữ số:
Kể từ số hỗ trợ tăng gấp đôi lên đến MAX_VALUE (ví dụ, 100! trong hình dạng kép như thế này: 9.332621544394415E157), không có vấn đề gì khi sử dụng BigDecimal.doubleValue(). Nhưng bạn không nên chỉ làm Math.pow (double, double) vì nếu kết quả lớn hơn MAX_VALUE, bạn sẽ chỉ nhận được vô cùng. SO: sử dụng công thức X^(A + B) = X^A * X^B để tách phép tính thành HAI quyền hạn, lớn, sử dụng BigDecimal.pow và nhỏ (còn lại của đối số thứ 2), sử dụng Math. pow, sau đó nhân lên. X sẽ được sao chép sang DOUBLE - đảm bảo nó không lớn hơn MAX_VALUE, A sẽ là INT (tối đa 2147483647 nhưng BigDecimal.pow không hỗ trợ số nguyên hơn một tỷ anyway), và B sẽ tăng gấp đôi, luôn nhỏ hơn 1. Bằng cách này bạn có thể làm như sau (bỏ qua hằng tôi tin vv):
int signOf2 = n2.signum();
try {
// Perform X^(A+B)=X^A*X^B (B = remainder)
double dn1 = n1.doubleValue();
// Compare the same row of digits according to context
if (!CalculatorUtils.isEqual(n1, dn1))
throw new Exception(); // Cannot convert n1 to double
n2 = n2.multiply(new BigDecimal(signOf2)); // n2 is now positive
BigDecimal remainderOf2 = n2.remainder(BigDecimal.ONE);
BigDecimal n2IntPart = n2.subtract(remainderOf2);
// Calculate big part of the power using context -
// bigger range and performance but lower accuracy
BigDecimal intPow = n1.pow(n2IntPart.intValueExact(),
CalculatorConstants.DEFAULT_CONTEXT);
BigDecimal doublePow =
new BigDecimal(Math.pow(dn1, remainderOf2.doubleValue()));
result = intPow.multiply(doublePow);
} catch (Exception e) {
if (e instanceof CalculatorException)
throw (CalculatorException) e;
throw new CalculatorException(
CalculatorConstants.Errors.UNSUPPORTED_NUMBER_ +
"power!");
}
// Fix negative power
if (signOf2 == -1)
result = BigDecimal.ONE.divide(result, CalculatorConstants.BIG_SCALE,
RoundingMode.HALF_UP);
Kết quả ví dụ:
50!^10! = 12.50911317862076252364259*10^233996181
50!^0.06 = 7395.788659356498101260513
Nguồn
2010-08-28 10:05:50
bạn có thể đưa ra một ví dụ về những gì bạn cố gắng để hoàn thành, 8^2 = 64 âm thanh người nghèo và 2^100^100 cần phải được thu nhỏ lại. – stacker
Tôi phải nói rằng tôi đã thử công thức lừa, và nó hoạt động tốt cho đến nay ngay cả với con số với hàng triệu chữ số! (Có vẻ như tôi không biết mọi thứ về đôi và int) ... Ví dụ: 50!^10! = 12.50911317862076252364259 * 10^233996181 50!^0.06 = 7395.788659356498101260513 Mã này hơi dài để đăng ở đây, nhưng bạn có ý tưởng về X^(A + B) = X^A * X^B ... Bây giờ Tôi đang cố gắng để hiểu làm thế nào và tại sao (và nếu) nó thực sự làm việc với những con số khổng lồ. –
Tôi đã đưa ra giải pháp ở đó http://stackoverflow.com/questions/11848887/bigdecimal-to-the-power-of-bigdecimal-on-java-android/22556217#22556217 –