基本数据类型在转换时的注意点

基本数据类型在转换时的注意点

以Java的两种常用数值类型为例long, int

常用的一种错误的防止溢出的写法是

int a = ???????, b = ????????;
long c = a * b;

当a*b超出Integer的表达范围时,例如 a = Integer.MAX_VALUE, b=2

此时按溢出处理

int a = Integer.MAX_VALUE, b = 2;
long c = a * b;
System.out.println(c);
// c = -2

IDEA 在编码时给出了一种建议

// a * b: integer multiplication implicitly cast to long 
int a = Integer.MAX_VALUE, b = 2;
long c = (long) a * b;
System.out.println(c);
// c = 4294967294

所以正确的操作是,在溢出可能发生的情况下,将某个绝对不会超出类型范围的的变量转换为接收的类型,例如案例里的int a, int b

再有复杂的案例, 如

long res = 0;
int[] arr = .... ;
int n = arr.length;
for (int i = 0; i < n; i++) {
    // 注意溢出问题
    // int 变量的运算, 即使使用 long 接收, 运算过程也会发生精度丢失
    // 因此将其中绝对不会超出 int 范围的值转换为 long
    // 保证整个运算使用 long 
    res = ( res + (long) arr[i] * (i - leftPos[i] + 1) * (rightPos[i] - i + 1)) 
%MOD;
    // 注意取模公式 (p*q)%MOD = (p%MOD * q%MOD)%MOD
}

对于 int[] 我们是能够保证不会出现溢出的,因此将它作为转换的对象,案例里的 (long)

表达式中的运算按照式中元素的最高精度计算,

案例中(long) arr[i]保证了表达式后的运算按照long类型计算,避免了溢出(在long范围内)

posted @ 2022-11-29 14:43  jentreywang  阅读(170)  评论(0编辑  收藏  举报