#include "iostream"
typedef unsigned char byte;
using namespace std;
int main(){
int x = 0x80000002;//-2的原码,但x不是-2,因为计算机中数值是以补码形式存储的
cout<<x<<endl;//-2147483646
int x2 = 0xFFFFFFFE;//-2,说明数值是以补码形式存储的---正数的补码就是本身,负数的补码是正数各位(位数由其类型int\short...决定)取反后加1【负数的补码也可以由负数的原码,符号位不变,其余各位(位数由 决定)取反后加1】,
cout<<x2<<endl;
byte x3 = -2;//0xFE
cout<<(int)x3<<endl;//254,0x000000FE,因为typedef unsigned char byte;所以x3即使等于-2,表示的也是正数
byte x4 = 0xFE;//-2
cout<<(int)x4<<endl;//254,0x000000FE
int x5 = -2;
x5 >>=2; //x5的补码的基础上移位。右移时,左边以原最高位(正数0,负数1)填充
cout<<x5<<endl;-1,可知负数移位不是简单的改变2的倍数关系
int x6 = 4;
x6 >>=2;
cout<<x6<<endl;//正数,2的倍数关系
int x7 = 8;
x7 >>=32;//对于short、char和int进行移位时,规定实际移动的次数是移动次数和int的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和long位数的余数,也就是移动66次和移动2次得到的结果相同。
cout<<x7<<endl;
int x8 = 8;
x8 <<=32;
cout<<x8<<endl;
cout<<sizeof(short)<<endl;//2
short x9 = 8;
x9 <<=32;
cout<<x9<<endl;
short x10 = 0xFFFE;
cout<<x10<<endl;//-2
x10 >>=2;
cout<<x10<<endl;
return 0;
}
/**
* 在计算机系统中,数值一律用补码来表示(存储)。 主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补 码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。 2、补码与原码的转换过程几乎是相同的。
*
* 计算机中的符号数有三种表示方法,即原码、反码和补码。它们均由符号位和数值部分组成,符号位的表示方法相同,都是用1表示“负”,用0表示“正”。
*
* 在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,规定实际移动的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是移动66次和移动2次得到的结果相同。
* 所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用大家知道的2的补码(two’s complement )这种编码来表示负数,也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加1。
* 1: 0000 0000 0000 0000 0000 0000 0000 0001
* -1:源码1000 0000 0000 0000 0000 0000 0000 0001;补码:1111 1111 1111 1111 1111 1111 1111 1111
*
* 负数的补码等于其绝对值的原码各位取反,然后整个数加1的数值。
*
同一个数字在不同的补码表示形式里头,是不同的。比方说-15的补码,在8位2进制里头是11110001,然而在16位2进制补码表示的情况下,就成了1111111111110001。在这篇补码概述里头涉及的补码转换默认把一个数转换成8位2进制的补码形式,每一种补码表示形式都只能表示有限的数字。
【例2】求-7的补码。
因为给定数是负数,则符号位为“1”。
后七位:-7的原码(10000111)→按位取反(11111000)(负数符号位不变)→加1(11111001)
所以-7的补码是11111001。
注:数0的补码表示是唯一的:
+0的补码=+0的反码=+0的原码=00000000
-0的补码=11111111+1=00000000(mod 2的8次方)
*/
/**
* @author yutian
*
*/
import java.util.*;
public class Test5_5 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte k = -2 ; //
System.out.println(k+"的二进制是:"+Integer.toBinaryString(k));
/**
* 得到-2的二进制是:11111111111111111111111111111110(补码)
* 由于java 中负数采用补码的方式表示,转成实际的原码应该是
* 符号位不变,各位取反+1
* 也即是
* 11111111111111111111111111111110的原码是
* 100000000000000000000000000000010
*/
k >>= 2 ;//补码的基础上移位,右移是,左边以最高位填充
/**
*根据补码理解:11111111111111111111111111111110
*得到k 向右移2位,移空位补1
*应该得到的值 11111111111111111111111111111111(补码),
*实际的值是: 100000000000000000000000000000001 (-1)
*/
System.out.println(k);//-1,可知负数移位不是简单的改变2的倍数关系
byte k2 = 4 ;
k2 >>= 2 ;
System.out.println(k2);//正数,2的倍数关系
}
}