Wrong result by Java Math.pow

2019-01-09 17:18发布

If you try to run the following code

public class Main {
   public static void main(String[] args) {
       long a = (long)Math.pow(13, 15);
       System.out.println(a + " " + a%13);
   }
}

You will get "51185893014090752 8"

The correct value of 13^15 is 51185893014090757, i.e. greater than the result returned by Math.pow by 5. Any ideas of what may cause it?

6条回答
一夜七次
2楼-- · 2019-01-09 17:46

A double has finite precision, its mantissa is 52 bits, which roughly equals 15 to 16 decimals. So the number you're trying to calculate can't be represented (exactly) by a double any more.

查看更多
Animai°情兽
3楼-- · 2019-01-09 17:49

You've exceeded the number of significant digits available (~15 to 16) in double-precision floating-point values. Once you do that, you can't expect the least significant digit(s) of your result to actually be meaningful/precise.

If you need arbitrarily precise arithmetic in Java, consider using BigInteger and BigDecimal.

查看更多
一夜七次
4楼-- · 2019-01-09 17:57

This is not a problem of precision. The Math.pow method performs an approximation of the result. To get the correct result use the following code.

long b = 13;
for(int i = 0; i != 14; i ++) {
    b = b * 13;
}
System.out.println(b);

The output is the expected result 51185893014090757L.

More generally, the Math.pow method usage should be avoided when the exponent is an integer. First, the result is an approximation, and second it is more costly to compute.

The implementation of Math.pow (and most other methods in the Math class) is based on the network library netlib as the package "Freely Distributable Math Library" (see StrictMath javadoc). The implementation in C is available at e_pow.c.

查看更多
【Aperson】
5楼-- · 2019-01-09 18:00

The correct answer is to provide the closest number which can be represented by a double

Have you checked whether this is the case or not?

查看更多
▲ chillily
6楼-- · 2019-01-09 18:03

it is because of the limit of holding digits in long by casting to double, float you may be able but it will have some errors, you should yourself handle the digits of the calculation by saving them in an array that's not an easy way

but in python programming language you can have the result of any length, it is so powerful!

be successful!!!

查看更多
神经病院院长
7楼-- · 2019-01-09 18:06

The problem is that as you get to higher and higher double values, the gap between consecutive values increases - a double can't represent every integer value within its range, and that's what's going wrong here. It's returning the closest double value to the exact result.

查看更多
登录 后发表回答