首先,要涉及到编码问题,需要了解到 原码 补码 反码 的概念
————————————————————我是分割线————————————————
在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.
1. 原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
即
[-127 , 127]
原码是人脑最容易理解和计算的表示方式.
2. 反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.
3. 补码
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
————————————————————我是分割线————————————————
之后,我们需要了解到有符号数首位代表的是符号,而java中是没有无符号数类型的,而且计算机中一律是使用 补码 存储数据的。所以接下来我们了解一下计算机中有符号数据转换成无符号数据的过程是怎么样的?
对于为什么要使用补码存储,可以参考链接,这里不赘述:http://blog.sina.com.cn/s/blog_9e67285801010vms.html
————————————————————我是分割线————————————————
因为计算机中的数据都是以补码存在的,所以对于正数没有区别(首位0表正数,1表负数),而对于负数,则需要首先取其补码,然后得到对应的数值。
以c语言中的数据为例:
main()
{ int
答案是b=65535。
分析:因为-1在计算机中的表示为:(以补码形式表示)1111 1111 1111
若把他看成无符号数则就是65535(十进制)
其具体求补码步骤为:
十进制形式就是无符号数 65535
反之,从无符号数转到有符号数也是一样的道理,如果无符号数时的在计算机中存储的首位为一(即转换后应为负数),要首先转换为补码计算。————————————————————我是分割线————————————————
好了,了解完有无符号数的转换之后,我们最后来考虑在java中的有无符号数的转换。
其实,了解并理解到这个地步,剩下的内容就没有多少意义了,上网也搜了一下,看了看别人说的关于java中有符号数转无符号数的文章,这里也提供一个链接:http://blog.163.com/tfn2008@yeah/blog/static/11032131920131211310727/
其他的文章也无非是围绕在,按位操作或是移位上,说白了,就是看你怎么来理解java中的有无符号数的转换,或是如何来定义java中的有无符号数的转换,可以理解为直接将计算机中的存储的补码截取2字节低位就是转换完了,也可以理解成其他的,所以再多的讨论也无益了。