精华内容
下载资源
问答
  • 移位

    千次阅读 2011-05-08 10:37:00
    移位

    经常会见到移位运算的表达式。一直困扰我。问过很多人,做单片机的海哥对移位很精通。
    	问过大家,还是不太懂,关键是解决的具体问题太少吧。、
    今天又搜索和思考了一下。再总结一下。

    1.左移右移都是对2进制数的小数点的移动,但是对于十进制数来说,右移相当于除以2,左移相当于乘以2.
    2.补位的问题。
    引用下“
    左移:对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。
    右移:移入0的叫逻辑右移,移入1的叫算术右移.”
    这些在计算机组成原理里头,确实学过,但是始终没有真正明白。
    3.读到一篇更为深入的文章。
    谈到了编译器根据计算机系统,在移位问题上,做的工作:
    (1)左移
    左移的时候,比如int类型,是32位的有符号类型。第一位是符号位,所以左移可以把首位为0的正数,移位变成首位为1的负数。
    对于int,0x8000 0000是int表示的最小的数-2147483648,(看上去是-0啊,不知道怎么算出来的这个值),溢出。
    (2)右移
    右移不会改变符号位。移位之后,在符号位根据以前的符号,填1或者0,这个和汇编语言的 算术移位 一样。
    (3)如果超过了数字的位数,那么,左移和右移,都是用要移位的位数 模 类型的位数,得到余数,按照余数移位。
    (4)总结:
    左移丢弃高位,会造成符号问题。低位用0来补。
    右移填充符号位。其他位用0补。

    对于有符号数中的负数,在内存中是二进制补码来表示的。右移的时候,采用算术移位,这里是对补码进行的移位操作,最后再变
    原码看十进制的值。
    =================================
    http://www.ok2002.com/cc/cc/v.asp?r=a222421465417264
    //C++  右移运算,把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。其值相当于除2
    
    
    #include<>
    using namespace std;
    
    char *__bit(char *str,const int &len,int a)
    {
    	int i;
    	for(i=len-1;i>=0;--i,a>>=1)
    		str[i]='0'+(1&a);
    	str[len]='/0';
    	return str;
    }
    
    void ()
    {
    	const int len=16;
    	char str[len+1];
    	cout<<(15>>2)<<" <-- 15>>2"<<endl;
    	cout<<__bit(str,len,15)<<" <-- 15"<<endl;
    	cout<<__bit(str,len,3)<<" <--3 "<<endl;
    }
    
    /*-----------------------
    设 a=15,a>>2表示把000001111右移为00000011(十进制3)。
    对于左边移出的空位,如果是正数则空位补0,
    若为负数,可能补0或补1,这取决于所用的计算机系统。
    移入0的叫逻辑右移,移入1的叫算术右移.
    -----------------------------*/
    
    /*-----------------
    3 <-- 15>>2
    0000000000001111 <-- 15
    0000000000000011 <--3
    Press any key to continue
    ------------------*/

    ======================================
    这篇文章写的很不错:
    http://www.rupeng.com/innersupesite/index.php/2941/viewspace-199
    C语言里的左移和右移运算
    2006-09-30 13:52
    
    (一)左移
    先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如:
    
    int i = 1;
    i = i << 2;  //把i里的值左移2位
    
    也就是说,1的2进制是000...0001(这里1前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成 000...0100,
    也就是10进制的4,所以说左移1位相当于乘以2,那么左移n位就是乘以2的n次方了(有符号数不完全适用,因为左移有可能导致符号变化,
    下面解释原因)
    
    (1)需要注意的一个问题是int类型最左端的符号位和移位移出去的情况.
    我们知道,int是有符号的整形数,最左端的1位是符号位,即0正1负,
    那么移位的时候就会出现溢出,例如:
    
    int i = 0x40000000; //16进制的40000000,为2进制的01000000...0000
    i = i << 1;
    
    那么,i在左移1位之后就会变成0x80000000,也就是2进制的100000...0000,符号位被置1,其他位全是0,变成了int类型所能表示的最小
    值,32位的int这个值是-2147483648,溢出.如果再接着把i左移1位会出现什么情况呢?在C语言中采用了丢弃最高位的处理方法,丢弃了
    1之后,i的值变成了0.
    
    (2)左移里一个比较特殊的情况是当左移的位数超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行
    移位,如:
    
    int i = 1, j = 0x8000 0000; //设int为32位
    i = i << 33;   // 33 % 32 = 1 左移1位,i变成2
    j = j << 33;   // 33 % 32 = 1 左移1位,j变成0,最高位被丢弃
    
    在用gcc编译这段程序的时候编译器会给出一个warning,说左移位数>=类型长度.那么实际上i,j移动的就是1位,也就是33%32后的余
    数.在gcc下是这个规则,别的编译器是不是都一样现在还不清楚.
    
    总之左移就是: 丢弃最高位,0补最低位
    
    
    (二) 右移
    再说右移,明白了左移的道理,那么右移就比较好理解了.
    
    右移的概念和左移相反,就是往右边挪动若干位,运算符是>>.
    
    右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如:
    
    int i = 0x80000000;
    i = i >> 1;  //i的值不会变成0x40000000,而会变成0xc0000000
    
    就是说,符号位向右移动后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移
    动余数个位.
    
         负数10100110 >>5(假设字长为8位),则得到的是  11111101
    
    
    (总结)
    
    总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除
    运算,这样会比循环效率高很多. 
    
    参考资料:http://hi.baidu.com/todaygoodhujun/blog/item/b8c10dd15ae4dfd3572c8417.html 
    
    
    ==============================================================================
    这篇文章更为深入:
    C语言中的移位操作,内容不多。不过有些地方你不注意,就疏忽了。 
    
      先做两个小题先。 
    
      (1)unsigned char x=3;       char是2个字节么?无符号的char呢? 有无符号都是16位。
    
      x<<1是多少?x>>1是多少?   左移1,是6,右移是2。1
    
      (2)char x=3;            这个char应该就是有符号的了。
    
      x<<1是多少?x>>1是多少?    既然是正数,那么应该和上面的一样。
    
      (3)char x=-3;          这个是负数,负数用补码表示,移位要对补码进行操作么?补码左移是什么个情况?
    
      x<<1是多少?x>>1是多少? 
    
      3写成二进制数是00000011;-3写成二进制数是(补码)11111101。  负数用二进制表示是表示成补码。
    
      程序执行的时候,操作的是数值的编码表示,也就是数值在内存中的二进制表示。比如说,程序取-3的时候,就去取11111101。 
    
      (1)对无符号数3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6;x>>1往
    右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是1。
    
      (2)对于有符号数3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6;x>>1往
    右边移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移这一点,C标准并没有明确地指定是使用逻辑右移还是算术右移
    但大多数的机器都使用算术右移,变成00000001,所以结果还是1。但是请注意,这只是说大多数的机器是这样的,你敢保证自己不会碰
    到特殊情况吗? 
    
      (3)对于有符号数-3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成11111010,结果是-6
    (先减1,再取反,就是1111 1001,取反1 000 0110,确实是-6)。 注意这里是补码的运算。

    往右移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移。大多数机器使用算术右移,变成11111110,结果是-2。 
    
      总结:左移时总是移位和补零。右移时无符号数是移位和补零,此时称为逻辑右移;而有符号数大多数情况下是移位和补最左边的位
    (也就是补最高有效位),移几位就补几位,此时称为算术右移。 
    
      附打印内存中字节编码的代码: 
    
    void print_char(char x) 
    
    { 
    
      unsigned char * bp=(unsigned char *)&x; 
    
      int size=sizeof(x); 
    
      for(int i=0; i<size; i++) 
    
           printf("%.2x", bp[i]); 
    
      printf("/n"); 
    
    }  
    展开全文
  • 移位

    2010-09-27 14:58:00
    1.汇编语言中的逻辑右移(SHR)是将各位依次右移指定位数,然后在左侧补0,算术右移(SAR)是将各位依次右移指定位数,然后...简单记忆: 逻辑移位:不考虑正负号  算术移位:考虑正负号 e g: 1000000000

    1.汇编语言中的逻辑右移(SHR)是将各位依次右移指定位数,然后在左侧补0,算术右移(SAR)是将各位依次右移指定位数,然后在左侧用原符号位补齐。
    2.高级语言右移运算符(>>)是将一个数的二进位全部右移若干位,低位移出部分舍弃,左补0。 
    3.高级语言右移和汇编语言中的逻辑右移功能一样,但不同于算术右移。 
    4.逻辑左移和算术左移一样,低位补0。
    简单记忆:
        逻辑移位:不考虑正负号   
      算术移位:考虑正负号

    e   g:             1000000000000000(右移2位)       0000000000000000(左移2位)       
      逻辑移位:0010000000000000                         0000000000000000   
      算术移位:1110000000000000                         1000000000000000   
        
      注:算术右移时,最前面是1时,补1,否则,补0。逻辑左移时,补0。     
              逻辑移位时,不用保留正负号(第一个),统一补0。

    逻辑移位(不管是左移位还是右移位)   都是空缺处补0   
        
      例如:     mov   ax   ,   1100_0111_0110_1000B   
                      mov   cl   ,   3   
                      shl   ax   ,   cl                                     ;   结果     ax   =   0011_1011_0100_0000   
        
                      mov   ax   ,   1100_0111_0110_1000B   
                      mov   cl   ,   3   
                      shr   ax   ,   cl                                     ;   结果     ax   =   0001_1000_1110_1101   
        
      算术移位要保证符号位的不改变(算术左移位补0,   算术右移位看符号位)   
        
      例如:     mov   ax   ,   1100_0111_0110_1000B   
                      mov   cl   ,   3   
                      sal   ax   ,   cl                                     ;   结果     ax   =   0011_1011_0100_0000   
        
                      mov   ax   ,   1100_0111_0110_1000B   
                      mov   cl   ,   3   
                      sar   ax   ,   cl                                     ;   结果     ax   =   1111_1000_1110_1101   
        
                      mov   ax   ,   0100_0111_0110_1000B   
                      mov   cl   ,   3   
                      sar   ax   ,   cl                                     ;   结果     ax   =   0000_1000_1110_1101    

    
    
    展开全文
  • 移位寄存器

    2020-12-09 01:57:52
    移位寄存器是暂时存放数据的部件,同时它还具有移位功能。 一、特点和分类 从逻辑结构上看,移位寄存器有以下两个显著特征:(1)移位寄存器是由相同的寄存单元所组成。一般说来,寄存单元的个数就是移位寄存器的...
  • 移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器
  • 逻辑移位 算术移位

    2019-12-18 18:35:04
    逻辑移位 逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补。 算术移位 算术移位 就需要分有符号型值和无符号型值 对于无符号型值,算术移位等同于逻辑移位。 而对于有符号型值 ,算术左移等同于逻辑左移,算术...

    逻辑移位
    逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补。

    算术移位
    算术移位 就需要分有符号型值和无符号型值
    对于无符号型值,算术移位等同于逻辑移位。
    而对于有符号型值 ,算术左移等同于逻辑左移,算术右移补的是符号位,正数补0,负数补1。

    展开全文
  • 移位寄存器(逻辑移位、算术移位、循环移位

    ​HDLBits网址:https://hdlbits.01xz.net/wiki/Main_Page

     

    1、逻辑移位寄存器

    题目

    Build a 4-bit shift register (right shift), with asynchronous reset, synchronous load, and enable.

    • areset: Resets shift register to zero.

    • load: Loads shift register with data[3:0] instead of shifting.

    • ena: Shift right (q[3] becomes zero, q[0] is shifted out and disappears).

    • q: The contents of the shift register.

    If both the load and ena inputs are asserted (1), the load input has higher priority.

     

    我的设计

        移位其实就是做乘法除法,左移为乘法,右移为除法,其他也没有什么好注意的地方了,直接贴代码

    module top_module(    input clk,    input areset,  // async active-high reset to zero    input load,    input ena,    input [3:0] data,    output reg [3:0] q);     always@(posedge clk or posedge areset)begin        if(areset) q <= 0;        else begin            if(load) q <= data;            else                 if(ena) q <= {1'b0,q[3:1]};        end    endendmodule

     

     

    2、算术移位寄存器

    题目

    Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by amount.

    There is no difference between logical and arithmetic left shifts.

    • load: Loads shift register with data[63:0] instead of shifting.

    • ena: Chooses whether to shift.

    • amount: Chooses which direction and how much to shift.

      • 2'b00: shift left by 1 bit.

      • 2'b01: shift left by 8 bits.

      • 2'b10: shift right by 1 bit.

      • 2'b11: shift right by 8 bits.

    • q: The contents of the shifter.

     

    我的设计

        算术移位和逻辑移位的区别就在于符号问题,逻辑移位无论左移还是右移,都直接补0,因为只是逻辑移位,简单来说就是为了移位而移位,不需要考虑符号的问题;而算术移位,左移是直接补0(与逻辑移位相同),右移的话补符号位。左移补0是因为高位溢出不用理,低位变成高位,所以低位补0;右移补符号位是因为要考虑正负号问题,最高位为符号位,如果符号位为0,正数右移补0,如果符号位为1,负数右移补1。

    module top_module(    input clk,    input load,    input ena,    input [1:0] amount,    input [63:0] data,    output reg [63:0] q);     always@(posedge clk) begin        if(load) q <= data;        else if(ena) begin            if(amount == 2'b00) q <= {q[62:0],1'b0};            else if(amount == 2'b01) q <= {q[55:0],{8{1'b0}}};            else if(amount == 2'b10) q <= {q[63],q[63:1]};            else if(amount == 2'b11) q <= {{8{q[63]}},q[63:8]};        end    endendmodule

     

    仿真结果

     

     

    3、循环移位寄存器

    题目

    Build a 100-bit left/right rotator, with synchronous load and left/right enable. A rotator shifts-in the shifted-out bit from the other end of the register, unlike a shifter that discards the shifted-out bit and shifts in a zero. If enabled, a rotator rotates the bits around and does not modify/discard them.

    • load: Loads shift register with data[99:0] instead of rotating.

    • ena[1:0]: Chooses whether and which direction to rotate.

      • 2'b01 rotates right by one bit

      • 2'b10 rotates left by one bit

      • 2'b00 and 2'b11 do not rotate.

    • q: The contents of the rotator.

     

    我的设计

        本题的循环移位寄存器有4种模式:加载、循环左移、循环右移、保持现状。(注意:时序逻辑不写完整的if...else...,是不会产生锁存器的

    module top_module(  input clk,  input load,  input [1:0] ena,  input [99:0] data,  output reg [99:0] q);  always @(posedge clk) begin    if (load)    // Load      q <= data;    else if (ena == 2'h1)  // Rotate right      q <= {q[0], q[99:1]};    else if (ena == 2'h2)  // Rotate left      q <= {q[98:0], q[99]};  endendmodule

     

    微信公众号

         建立了一个微信公众号“Andy的ICer之路”,此公众号主要分享数字IC相关的学习经验,做公众号的目的就是记录自己的学习过程,很多东西回过头来可能就忘记了,为了记住知识和分享知识,希望自己可以保持更新,有兴趣的朋友可以关注一下!

     

    展开全文
  • 算术移位逻辑移位

    2019-02-20 19:31:46
    请问:上面的变量i是采用逻辑移位还是算术移位呢? 逻辑移位,简单理解就是物理上按位进行的左右移动,两头用0进行补充,不关心数值的符号问题。 算术移位,同样也是物理上按位进行的左右移动,两头用0进行补充,...
  • 移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器移位寄存器
  • 逻辑移位和算数移位

    2019-12-29 20:01:48
    逻辑移位不看符号 算数移位看符号
  • 本文主要讲了avr单片机中左移位和右移位指令,下面一起来学习一下
  • 移位运算

    2020-07-16 16:59:05
    移位运算 1.逻辑移位 2.算数移位 3.循环移位
  • 算术移位和逻辑移位

    千次阅读 2017-10-11 18:40:59
    算术移位,逻辑移位,正数/负数移位
  • 逻辑移位与算术移位

    2020-03-07 16:56:53
    逻辑移位与算术移位 1.逻辑移位: 不论是左移还是右移都是直接补0。 2.算术移位: 当机器数为正时: 无论左移、右移,原码、补码、反码均补0。 当机器数为负时: 1)原码:由于除符号位外,数值位与真值相同,所以...
  • 逻辑移位和算术移位

    2019-10-04 21:05:11
    没学过汇编的估计都没听说过...算术移位 sar - 保留最高位不变,其他的数移位 逻辑移位 shr - 无视最高位 循环移位 - ror rcr 分带进位与不带进位(cf) 两种移位,移除的数字都会进入cf, 带进位的操作相当于把c...
  • 通用处理器中的快速并行提取移位和并行沉积移位
  • 移位运算实验

    2018-11-30 18:41:20
    移位运算实验报告,逻辑移位,循环移位。计算机组成原理实验报告。
  • 逻辑移位与算术移位的区别: 逻辑移位是对逻辑数或无符号数进行的移位,其特点是不论左移还是右移,空出位均补0,移位时不考虑符号位 算术移位是对带符号数进行的移位操作,其关键规则是移位时符号位保持不变,空出...
  • 算术移位和逻辑移位详解

    千次阅读 多人点赞 2019-12-17 09:51:02
    大部分的C编译器,用移位的方法得到代码比调用乘除法子程序生成的代码效率高。 移位运算是将数值向左向右移动,对于十进制来说就是实现放大十倍和缩小十倍的效果,而对于二进制而言就是放大两倍和缩小两倍的效果 ...
  • 移位指令

    2020-04-20 15:51:26
    移位指令是一组经常使用的指令,包括:算数移位、逻辑移位、双精度移位、循环移位、带进位的循环移位; 移位指令都有一个指定需要移动的二进制位数的操作数,该操作数可以是立即数,也可以是CL的值;在8086中,该操作数只能...
  • 桶型移位寄存器

    2019-04-29 21:56:31
    用Verilog硬件描述语言实现了64位移位寄存器任意方向、任意规模的快速移位
  • 大部分的C编译器,用移位的方法得到代码比调用乘除法子程序生成的代码效率高。最近在看Java源码的时候,看到了一些位运算的操作,特意在整理了一下移位运算,不整理不知道,一整理吓一跳,那就随着一起看下去吧!移位...
  • 一、逻辑移位 逻辑移位的对象是无符号数,移位规则:逻辑左移时,高位移丢,低位添0;逻辑右移时,低位移丢,高位添0 二、算术移位 算术移位的对象是有符号数,在移位的过程中符号位保持不变。 三、循环移位 ...
  • 逻辑移位和算术移位的区别

    万次阅读 多人点赞 2018-05-01 18:02:27
    逻辑移位 逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补。 算术移位 算术移位 就需要分有符号型值和无符号型值 对于无符号型值,算术移位等同于逻辑移位。 而对于有符号型值 ,算术左移等同于逻辑左移,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,643
精华内容 9,457
关键字:

移位