关于C语言移位的问题 5
“对于一个由w位组成的数据类型,如果要移动k>=w位会得到什么结果呢?......C语言标准很小心地规避了说明在这种情况下该如何做。在许多机器上,当移动一个w位的值时,移位指令只考虑位移量的低log 2 w位(2是底数,格式不知道怎么打不出来),因此实际上位移量就是通过计算k mod w得到的。“
不理解的地方是:
①"移位指令只考虑位移量的低log 2 w位“,是什么意思?是不是说不管左移还是右移,都会从低log 2 w位开始?
②“当移动一个w位的值时,移位指令只考虑位移量的低log 2 w位”怎么推论出来“===>因此实际上位移量就是通过计算k mod w得到的。”?
财富值不多了,请大家谅解! 展开
当移动一个w位的值时,移位指令只考虑位移量的低log 2 w位
c语言中规定的w位数一般为8、16、32、64。
假设k的低log 2 w位的值为u
那么高于log 2 w位的值显然都是w的倍数
k=n*w+u
其中n>=0,当n=0的时候,k<w,n>=1的时候,k>=m
所以k mod w = (n*w+u) mod w = u
当移动一个ω位的值时,移位指令只考虑位移量的低log₂ ω位,因此实际上位移量就是通过计算k mod ω得到的。
移位指令只考虑位移量的低log₂ ω位,这句话指的是把位移量k看成二进制序列,然后只考虑该序列的低位,比如移动ω=32位的数据类型,位移量k为36时,实际上移位指令只需要考虑位移量(位移量36 = 100100),即100100这个序列的后五位,也就是00100,因此实际位移量就是4,和36mod32一致。
所以两个疑问就很好理解了:
①移动是从序列第一位开始,只是实际位移量把大于ω位的部分都舍去了
②为什么只需考虑位移量对应二进制序列的低log₂ ω位呢?因为假设你把32位的序列看成一个循环序列,移动32位正好一圈,所以只要你移动32的整数倍,那么都正好移动回原来的序列,这个过程和对32取模结果一样,所以又得出结论→“实际上位移量就是通过计算k mod ω得到的”,也可以知道,这个值是一定小于ω的。
★容易误解的点在于这里所说的低log₂ ω位是位移量k所对应序列的log₂ ω个低权位,和实际位移量或者位移位数并没有直接关系。36 = 100100,0 0 1 0 0是五个低权位(6个数位按权展开相加之和是36),而实际位移量并不是log₂ 32 = 5而是(00100)₂ = 4,但是有一点关系是确定的,实际位移量一定小于2^5 = 32位。
而使用k mod w的方式计算,33 mod 32 得到 1,移1位。
两种方法计算得到的结果是统一的。
2014-02-20
谢谢你的解答。可是和文中的意思好像不同吧。