有符号数 无符号数 原码 补码 反码 java用补码表示

计算机数字的储存分为:1、无符号数,2、有符号数

  • 无符号数:只能表示正数。每一位数都代表2的幂次方。只有地址用无符号数,无符号数不进行算术操作,之进行指针的加减。地址并不会造成错误的结果,而是产生一个空操作(气泡),所以无符号数不考虑溢出。
  • 有符号数:可以表示负数。有符号数有三种表示法:1、原码,2、补码(计算机系统中,数值一律用补码来表示和存储),3、反码

  (此处我们以8位有符号数举例)

  • 原码:最高位符号位代表简单的正负符号,其他位为1代表 2^i
    • 举例:0000_0001代表1,1000_0001 代表-1
    • 求相反数:改变符号位
    • 缺点:符号位需要额外的步骤来运算,因为结果不能提前知道。夭折得早。
  • 补码:规定 x+ ~x=1111_1111= -1。最高位符号位为1代表 -2^7,其他位为1代表 2^i,且有1111_1111= -1
    • 举例:  
      •   0000_0000=0
      •   0000_0001=2^0=1
      •   0000_0010=2^1=2
      •   0000_0011=2^1+2^0=2+1=3
      •   ……
      •   0111_1111=2^6+2^5+2^4+2^3+2^2+2^1+2^0=128-1=127(最大)
      •   1000_0000= -2^7= -128(最小)
      •   1000_0001= -2^7+2^0= -128+1= -127
      •   1000_0010= -2^7+2^1= -128+2= -126
      •   ……
      •   1111_1111= -2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0= -128+64+32+16+8+4+2+1=-1
    • 求相反数:因为 x+ ~x= -1,所以 -x= ~x+1  
    • 缺点:无,大家都在用
  • 反码:规定 x+~x=0。所有的正数取反就为相应的负数,正数的最高位必须预留为0,来保证取反之后负数为1而不会变成另一个正数。考虑所有正数: 0——0111_1111,就有所有负数:1111_1111——1000_0000
    • 举例:
      •   0000_0000=0,1111_1111= -0(0+(-0)=0)
      •   0000_0001=1,1111_1110= -1
      •   0000_0010=2,1111_1101= -2
    • 求相反数:反码每一位的意义没有补码直接,所以是按补码求相反数运算再多一个减一操作来用反码表示
    • 缺点:运算步骤比补码多。仅在早期的科学计算有优势。

小测试:java是补码还是反码?

补码。因为:

  证据1:

1         System.out.println(~0);
2         System.out.println(~1);
3         System.out.println(~2);
4         //-1
5         //-2
6         //-3
7         //如果是反码应该输出:0,-1,-2

  证据2:

1         System.out.println(Integer.MAX_VALUE);
2         System.out.println(Integer.MIN_VALUE);
3         //2147483647
4         //-2147483648
5         //如果是补码就应该是:2147483647,-2147483647,因为补码正负数个数相等,有正零、负零

  证据3:

1         System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
2         System.out.println(Integer.toBinaryString(-Integer.MAX_VALUE));
3         //01111111111111111111111111111111
4         //10000000000000000000000000000001取反加一
原文地址:https://www.cnblogs.com/towerbird/p/11633317.html