原码、反码与补码的基础内容
原码、反码与补码在计算机基础中都是很重要的知识,可以将补码用在数值计算中。
一般将数值的最高位设置为符号位:
- 正数符号位为0
- 负数符号位1
原码
原码是直接将数值转换为二进制的码。
例如(以8位举例):
1的原码为 :0000 0001
-1的原码为:1000 0001
反码:
-
正数的反码就是原码
-
负数的反码就是将原码除了符号位之外,按位取反
例如:
1的反码 :0000 0001
-1的反码:1111 1110
补码
- 正数的补码还是原码
- 负数的补码是反码+1
例如:
1的补码为: 0000 0001
-1的补码为:1111 1111
补码与原码的转换
因为正数的原码=反码=补码,所以,这里仅仅是讨论负数的原码与补码的相互转换。
负数补码转换为原码:
- 符号位不变,先将补码-1,然后取反
- 或者,先取反,然后+1
负数原码求补码:
- 将符号位不变,按位取反,然后加1,获得补码
如果是先在取反之前,将数值+1,可能会出现也写错误,因为如果该数值为-1,加1后就是0,符号为也发生变化,所以不推荐先加后变,应该是先变后加。
总结:
- 正数的原码=反码=补码
- 负数的原码变为反码:符号位不变,剩余位取反
- 负数的反码变补码:符号位不变,反码+1
- 负数的原码变为补码:符号位不变,取反后加1
- 负数的补码变为原码:符号位不变,取反后加1或者先减一后再取反
数值溢出
因为有符号的数值的最高位为符号位,所以再数值达到最大值和最小值的时候,再增大或者减小,将会产生数值溢出。
数据溢出就是:当某一种类型的数值已经达到了此类型能够保存的最大值之后,再继续扩大,或者达到了最小值后再继续缩小,就会出现数据溢出问题。
Java中的整型的取值范围为:-2147483648 ~ 2147483647
当java达到了最大值2147483647时,再增加1,输出的结果为-2147483648
int i = Integer.MAX_VALUE;
System.out.println("int 的最大值为:" + i);
System.out.printf("最大值的16进制为:%x \n", i);
int j = i+1;
System.out.println("int 最大值加1为:" + j);
System.out.printf("16进制为:%x \n", j);
输出的结果为:
int 的最大值为:2147483647
最大值的16进制为:7fffffff
int 最大值加1为:-2147483648
16进制为:80000000
当Java达到最小值时,再减1将会输出2147483647
int min = Integer.MIN_VALUE;
System.out.println("int 的最小值为:" + min);
System.out.printf("最小值的16进制为:%x \n", min);
int k = min - 1;
System.out.println("int的最小值减一为:"+ k);
System.out.printf("16进制为:%x \n", k);
输出的结果为:
int 的最小值为:-2147483648
最小值的16进制为:80000000
int的最小值减一为:2147483647
16进制为:7fffffff
因为一个数据类型的最大值和最小值是一个循环,也就是说在最大值的基础上再扩大数值或者在最小值的基础上再缩小数值,会跳到相反的最值上面