Java中Math.pow返回double赋值给int无报错的原因咨询
为什么
sum += Math.pow(2, i) * arg[i]没出现编译错误? 嘿,这个问题问得很到位!你注意到了Math.pow()返回double但sum是int类型的矛盾点,但代码却能正常编译——这可不是编译器偷偷给你加了(int)强制转换,而是Java里复合赋值运算符(比如+=)的内置规则在起作用,我给你掰碎了讲:
1. +=的本质:自带隐式窄化转换
Java规定,像+=这种复合赋值运算符,等价于把右侧表达式的结果强制转换为左侧变量的类型后再赋值。换句话说:
sum += X;
完全等价于:
sum = (int) (sum + X); // 因为sum是int类型
放到你的代码里,就是编译器自动帮你做了最后那步强制转换,但这是+=运算符本身的特性,不是额外加的转换哦。
2. 一步步看类型推导过程
咱们把你的代码拆解成步骤:
Math.pow(2, i)返回double类型,arg[i]是int,所以乘法运算时arg[i]会被自动提升为double,最终Math.pow(2, i) * arg[i]的结果是double。- 接下来
sum(int类型)会被自动提升为double,和前面的double结果相加,得到一个double类型的临时值。 - 最后
+=运算符把这个double临时值隐式转换为int,赋值回sum。
3. 要小心的坑:精度丢失
虽然编译没问题,但这种隐式转换可能会踩坑:当Math.pow(2, i)的结果超过int的取值范围(比如i >=31时,2^31已经比int最大值2147483647大),转换后会得到错误的数值(比如变成负数)。
举个实际的例子:
int sum = 0; int[] arg = {1}; // i=31时,Math.pow(2,31)是2147483648.0,转成int就成了-2147483648 for(int i=31; i < arg.length+31; i++) { sum += Math.pow(2, i) * arg[i-31]; } System.out.println(sum); // 输出-2147483648
内容的提问来源于stack exchange,提问作者안준호
相关产品推荐
相关产品推荐

