为什么用math.pow()递减integer.min\u值会返回相同的值?

wooyq4lh  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(371)

执行时:

int p=-2147483648;
        p-=Math.pow(1,0);  
        System.out.println(p);
        p-=1;
        System.out.println(p);
Output: -2147483648
         2147483647

那么为什么math.pow()不溢出这个数字呢?

wf82jlnq

wf82jlnq1#

我们从观察开始讨论 -2147483648 == Integer.MIN_VALUE (= -(2³¹)).
表达式 p -= Math.pow(1,0) 具有来自 doubleintMath.pow(...) 返回一个 double . 带有显式强制转换的表达式如下所示

p = (int) (p - Math.pow(1,0))

ideone演示
更进一步,我们得到

double d = p - Math.pow(1,0);
p = (int) d;

ideone演示
如我们所见, d 有价值吗 -2.147483649E9 (= -2147483649.0 ) < Integer.MIN_VALUE .
cast的行为由java14jls控制,§5.1.3:
5.1.3. 缩小基本转换
...
浮点数到整数类型的缩小转换 T 采取两个步骤:
在第一步中,将浮点数转换为 long ,如果 Tlong ,或 int ,如果 Tbyte , short , char ,或 int ,如下所示:
如果浮点数是 NaN (§4.2.3),转换第一步的结果为 int 或长0。
否则,如果浮点数不是无穷大,则将浮点数舍入为整数值 V ,使用ieee 754向零舍入模式向零舍入(§4.2.3). 然后有两种情况:
如果 Tlong ,此整数值可以表示为 long ,则第一步的结果是 long 价值 V .
否则,如果此整数值可以表示为 int ,则第一步的结果是 int 价值 V .
否则,必须满足以下两种情况之一:
值必须太小(一个很大的负值或负无穷大),并且第一步的结果是类型的最小可表示值 int 或者 long .
值必须太大(大幅度的正值或正无穷大),并且第一步的结果是类型的最大可表示值 int 或者 long .
第二步:
如果 Tint 或者 long ,转换的结果就是第一步的结果。
...

tktrz96b

tktrz96b2#

请注意 Math.pow() 使用double类型的参数进行操作并返回double。将其转换为int将产生预期的输出:

public class MyClass {
    public static void main(String args[]) {
        int p=-2147483648;
        p-=(int)Math.pow(1,0);  
        System.out.println(p);
        p-=1;
        System.out.println(p);
    }
}

上述操作产生以下输出:
2147483647
2147483646

相关问题