这整理了下之前刷题遇到的问题,发现自己对于自动、强制类型转换的逻辑理解不够透彻
专门研究了下。
先来看下引起我疑问的代码
1 // leetcode 第9题,回文数 2 public boolean isPalindrome(int x) { 3 if (x<0) return false; 4 long res = 0,temp=x; 5 while(temp!=0){ 6 res=res*10+temp%10; 7 temp=temp/10; 8 } 9 return (int)res==x ? true:false; 10 } 11 12 13 // leetcode 69题 x的平方根 14 public int mySqrt(int x) { 15 int left = 1,right = x,mid=0,res=0; 16 while(left<=right){ 17 mid=left+(right-left)/2; 18 if((long)mid*mid<=x){ 19 res=mid; 20 left=mid+1; 21 }else{ 22 right=mid-1; 23 } 24 } 25 return res; 26 } 27 28 // leetcode 第98题 验证 29 Long min = Long.MIN_VALUE; 30 public boolean isValidBST(TreeNode root) { 31 if(root==null){ 32 return true; 33 } 34 35 if(!isValidBST(root.left)){ 36 return false; 37 } 38 39 if(root.val<=min){ 40 return false; 41 } 42 min = (long)root.val; 43 44 return isValidBST(root.right); 45 }
上面3个方法中都出现了强制类型转换,用途却存在一定的差异
下面我们先来梳理一下什么是类型转换的2种形式,强制类型转换和自动类型转换
(1)自动类型转换
即,范围小的类型可以直接赋值个范围大的类型,例如
1 int a = 1; 2 // int可转换为long、float和double; 3 long b = a; 4 // long可转换为float和double; 5 float c = b; 6 // float可转换为double; 7 double d = c;
将小范围的值赋值给大范围的类型,不存在精度损失的情况,因此可以直接赋值
(2)强制类型转换
自动类转换是将小范围的值赋给大范围的类型,强制类型转换则相反,是将大范围
的类型赋值给小范围的值,我们将上面的例子反过来看下。
1 double d = 2.75d; 2 float c = (float)d; 3 long b = (long)c; 4 int a = (int)b;
(3)二元运算符对计算结果的影响
其规则为
1、如果2个操作数有1个为Long,则结果为Long
2、没有long时,结果为Int,即使2边全为short、byte
3、2个操作数只要有1个是double,则结果为double
4、2个操作数都为float时,结果才为float
结合以上几点,我们再来看开头抛出的几个方法中对类型转换的应用
long res = 0,temp=x; return (int)res==x ? true:false;
首先int类型的变量可以直接赋值给long类型的变量,不会损失精度
其次,显然x发翻转后的值可以完整的保存在long类型的变量中,需要强转为Int才能判断是否溢出
if((long)mid*mid<=x)
这里由于2测都是int类型,mid*mid在溢出情况下条件依然成立,因此需要强转为long类型来协助比较大小
min = (long)root.val;
这里则是最简单的由大转小的类型转换。
我们可以总结一下
(1)不同类型的值可以直接比较,不涉及类型转换
(2)二元运算符会自动将小的类型转换为大的类型
(3)比较运算符不涉及类型转换,因此在考虑溢出的情况时需要手动实现强制类型转换