Java math.pow()返回错误答案

时间:2016-05-12 20:23:16

标签: java

我使用的是Math.pow()方法,结果与我从计算器得到的结果不同。

我使用的代码:

public static int getSum(int a, int b, int c, int d){
    return (int)(d*Math.pow(16.0,6.0)+c*Math.pow(16.0,4.0)+b*Math.pow(16.0,2.0)+a);
}

打印

 getSum(0,0,128,191)

打印出2147483647 而谷歌计算器显示3212836864。

是什么导致这种情况?

5 个答案:

答案 0 :(得分:5)

只是为现有答案添加一个解释(如果有人想知道为什么没有整数溢出):

The spec在5.1.3下说。缩小原始转换

  

在第一步中,浮点数转换为a   long,如果T很长,或者是int,如果T是byte,short,char或int,   如下:

     
      
  • 如果浮点数为NaN(§4.2.3),则转换的第一步结果为int或long 0。

  •   
  • 否则,如果浮点数不是无穷大,浮点值将四舍五入为整数值V,舍入为
      使用IEEE 754舍入零模式(§4.2.3)向零。然后
      有两种情况:

         
        
    • 如果T很长,并且此整数值可以表示为long,则第一步的结果是长值V。

    •   
    • 否则,如果此整数值可以表示为int,则第一步的结果是int值V.

    •   
  •   
  • 否则,以下两种情况之一必须为真:

         
        
    • 该值必须太小(大幅度或负无穷大的负值),第一步的结果是   int或long类型的最小可表示值。

    •   
    • 值必须太大(大幅度或正无穷大的正值),第一步的结果是   int或long类型的最大可表示值。

    •   
  •   

因此,Math.pow返回的double值会转换为代表性最大的int(即Integer.MAX_VALUE)。

请注意,此部分特定于浮点数转换。如果你的方法是例如定义为(注意额外强制转换为long

public static int getSum(int a, int b, int c, int d){
    // Casting twice doesn't make sense. It's just here for demonstration.
    return (int)(long)(d*Math.pow(16.0,6.0)+c*Math.pow(16.0,4.0)+b*Math.pow(16.0,2.0)+a);
}

规范中的相应部分将是

  

将有符号整数缩小转换为整数类型T.   简单地丢弃除n个最低位之外的所有位,其中n是数字   用于表示类型T的位数。除了可能的丢失   有关数值大小的信息,这可能会导致   结果值的符号与输入符号不同   值。

并且您的方法将返回-1082130422(也就是整数溢出)。

答案 1 :(得分:4)

Java int具有存储2^32的功能,如果已签名,则一半由负数使用。对于正数,最多可以存储2^31 -1 = 2147483647。您需要更大的类型来执行此任务,使用long并且签名时最多可以存储9 223 372 036 854 775 807

答案 2 :(得分:3)

2,147,483,647是int可以容纳的最大值。如果你需要更大的数字,比如在这种情况下,请让你的函数返回很长的时间。

答案 3 :(得分:0)

java中整数的最大值为2,147,483,647。您应该将其保持为双倍值Math.ceil()Math.floor()。您也可以将其转换为long值,因为这是一个64位二的补码整数。

答案 4 :(得分:0)

将您的代码更改为以下内容:int - > 32位(2 ^ 32 -1) 测试最大长度的简便方法是System.out.println(Integer.MAX_VALUE); ==> 2147483647

public static Long getSum(int a, int b, int c, int d) {
    return (long) (d * Math.pow(16.0, 6.0) + c * Math.pow(16.0, 4.0) + b * Math.pow(16.0, 2.0) + a);
}