隐式转换问题总结

87 阅读3分钟

问题1::long sq = (long)middle * middle;和long sq = middle * middle的区别是什么 极端情况下计算结果会有什么不同

详细解释

第一种写法

long sq = (long)middle * middle;

在这行代码中:

  1. (long)middlemiddle 的值从 int 类型转换为 long 类型。
  2. 然后进行乘法运算:一个操作数是 long,另一个操作数是 int
  3. Java 会将 int 操作数提升为 long 类型,并在 long 类型范围内进行乘法运算。
  4. 最后将结果赋值给 sq,这是一个 long 类型的变量。

这种写法可以避免 int 类型乘法运算导致的溢出问题。

第二种写法

long sq = middle * middle;

在这行代码中:

  1. middleint 类型。
  2. middle * middleint 类型的乘法运算。
  3. 如果 middle 的值较大,这个乘法运算可能会导致溢出,结果仍然是 int 类型。
  4. 然后将结果赋值给 sq,这时 int 类型的结果会被转换为 long 类型。

这种写法可能导致溢出,因为乘法运算是在 int 类型范围内进行的。

极端情况比较

假设 middle 的值为 50000,我们比较这两种写法的结果:

第一种写法

long sq = (long)middle * middle;
  • (long)middlemiddle 转换为 long,即 50000 转换为 50000L
  • 然后计算 50000L * 50000L,结果是 2500000000L
  • sq 的值是 2500000000L

第二种写法

long sq = middle * middle;
  • 计算 middle * middle,即 50000 * 50000,在 int 范围内进行。
  • 50000 * 500002500000000,这超出了 int 的最大值 2147483647,导致溢出。
  • 溢出结果是一个错误的 int 值,例如 2500000000 的二进制表示超过了 int 的范围,结果可能是负数或其他错误的值。
  • 然后将这个错误的 int 结果转换为 long 类型并赋值给 sq,但溢出已经发生,sq 的值不正确。

示例代码比较

以下代码展示了不同的计算结果:

public class Main {
    public static void main(String[] args) {
        int middle = 50000;

        // 第一种写法:类型转换后进行乘法运算
        long sq1 = (long)middle * middle;
        System.out.println("First method result: " + sq1); // 输出正确结果:2500000000

        // 第二种写法:乘法运算后进行类型转换
        long sq2 = middle * middle;
        System.out.println("Second method result: " + sq2); // 输出溢出结果:-1794967296
    }
}

结论

  • 第一种写法:通过将 middle 转换为 long 类型后进行乘法运算,可以避免溢出,结果正确。
  • 第二种写法:在 int 范围内进行乘法运算,可能导致溢出,结果不正确。

因此,在需要进行大数乘法时,使用第一种写法 (long)middle * middle 是更安全且正确的方式。