基本数据类型在转换时的注意点
以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范围内)