这个问题本来没什么值得关注,但是强转如果发生溢出,结果会有些奇怪。加上我是在写协议的校验和函数时遇到这个问题的,相关的概念很容易让人头大
先上结论:
1.源代码中所有数值均为其真值
,例如可以看到有负号”-“
2.机器存储的只有补码
3.强制转换结果是使用补码
来截断得到的(不包括浮点型数)
4.打印出的是十进制的真值
5.校验和使用的是无符号数
6.java中没有无符号数,可以使用高一级的类型表示低一级的无符号数(因为正数的补码与原码相同)
下面看一下强制转换的例子
上面的两个语句分别会输出:-127
和127
,现在来解释一下:
在java中,整数数值默认是int类型,第3点提到要要用补码截断,int型数值0x81的补码是0x00000081,截断的结果是只保留其最后8位,即剩下0x81,即二进制的10000001,这是补码,对应的原码为11111111,其十进制的真值
是-127
-0x81的补码为0xFFFFFF7F,截断的结果是0x7F,即二进制的01111111,这是补码,而由于符号位是0,对应的原码就是其本身,故其十进制真值为127
再来看这两个函数:
第一个函数的目的是得到byte[]数据的校验和,然而java没有无符号数据,所以变量sum用的是long类型,因此在加法运算时,byte数据都会被提升为long类型,所以函数中加法的效果与无符号数加法相同
第二个函数来自http://blog.csdn.net/tang9140/article/details/43404385,其目的是得到一个整数型数据得到后len个字节,函数的关键是利用强制转换得到最后8位,然后右移8位,直到得到len个字节。这是可行的但是如果要从byte数组取出原来类型的数,也要对应的转化,详见原文的处理函数