C/C++以及Java中移位的问题以及负数移位

来源:互联网 发布:大闹天宫神器进阶数据 编辑:程序博客网 时间:2024/05/06 21:20
#include "iostream"typedef unsigned char byte;using namespace std;int main(){int x = 0x80000002;//-2的原码,但x不是-2,因为计算机中数值是以补码形式存储的cout<<x<<endl;//-2147483646int x2 = 0xFFFFFFFE;//-2,说明数值是以补码形式存储的---正数的补码就是本身,负数的补码是正数各位(位数由其类型int\short...决定)取反后加1【负数的补码也可以由负数的原码,符号位不变,其余各位(位数由  决定)取反后加1】,cout<<x2<<endl;byte x3 = -2;//0xFEcout<<(int)x3<<endl;//254,0x000000FE,因为typedef unsigned char byte;所以x3即使等于-2,表示的也是正数byte x4 = 0xFE;//-2cout<<(int)x4<<endl;//254,0x000000FEint 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;//2short 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的倍数关系}}


原创粉丝点击