| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 737 人关注过本帖
标题:移位输出问题
只看楼主 加入收藏
霹雳键盘
Rank: 1
等 级:新手上路
帖 子:9
专家分:4
注 册:2011-4-6
结帖率:100%
收藏
 问题点数:0 回复次数:4 
移位输出问题
void main()
{
    int a=2;
    printf("%d ",2>>32);
    printf("%d",a>>32);
}
结果不一样.......
搜索更多相关主题的帖子: void 
2011-04-19 22:37
ucyan
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:61
专家分:198
注 册:2011-4-12
收藏
得分:0 
void main()
{
    int a=2;
    printf("%d ",2>>32);
    printf("%d",a>>32);
}
>> 为右移
a >> 32 为右移32位,即为除以2的32次方,但是由于int的范围为
-2^31到2^31-1 但是上述的结果已经超过这个范围,我理解为可能是
超过了int的范围,它得出的结果可能是随机值(它与编译器有关)
可能有错误~~
2011-04-20 00:09
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9031
专家分:54061
注 册:2011-1-18
收藏
得分:0 
超过范围的,其行为未定义
收到的鲜花
  • 霹雳键盘2011-04-20 19:42 送鲜花  3朵   附言:我很赞同
2011-04-20 08:12
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
收藏
得分:0 
shl shr逻辑移位 空出来的位置全部补0
sar sal算术移位 sal与shl等价    sar填补和符号位相同  ==》所以只要赋值后移位操作结果应该是可以算出来的
printf("%x ", 2 >> 32);
    push 0
    push offset string "%d " (00420020)
    call printf (00401080)
    add esp, 8
先是压入两个参数 就是两个push 语句 参数的压入顺序从右往左边压入 然后调用printf函数 红色标记为对应的地址
因为2 >> 32 这条语句在编译的时候就可以得出结果(都是常量) 结果也是没有问题的 为0 最后执行的打印 输出也是0
printf("%d ", a >> 32);
    mov eax, dword ptr [ebp-4] ;从运行栈中取出临时变量a 送往eax (eax) = 2
    sar eax, 20h ;这里执行移位操作  如果按照一般的不走这里 (eax)= 0
    push eax
    push offset string "%d" (0042001c)
    call printf (00401080)
    add esp, 8;从栈顶出栈 弹出两个参数  保证调用前后的一致
执行移位后的eax值:
图片附件: 游客没有浏览图片的权限,请 登录注册
可以看到依然是2

大家可以测试下下面的代码 看看是不是一样 环境VC++6.0:
printf("%d ", 2>>1);
    push 1
    push offset string "%d " (00420020)
    call printf (00401080)
    add esp, 8
for (i=32; i>=1; --i)
    mov dword ptr [ebp-8], 20h
    jmp main+56h(0040b7c6)
    mov eax, dword ptr[ebp-8]
    sub eax, 1
    mov dword ptr [ebp-8], eax
    cmp dword ptr [ebp-8], 1
    jl main+5eh(0040b7ce)
{
    (a<<4);
}
    jmp main+4dh (0040b7bd)
printf("%d ", a);
    mov ecx, dword ptr[ebp-4]
    push ecx
    push offset string "%d " (00420020)
    call printf (00401080)
    add esp, 8
从上面的汇编结果可以看到
{
    (a<<4);
}这里根本没有执行   我试着把4换成1 2 100 这些数字 也是一样的 不会有汇编代码产生  所以最后输出的结果(a)是不变的
最后试着把代码改成这样子:
a = (a<<4);
    mov ecx, dwrod ptr[ebp-4]
    sar ecx, 4
    mov dword ptr[ebp-4], ecx
这会就有了  结果在一定的范围之内是正确的

那么就看下 下面错误:
程序代码:
#include <stdio.h>

void main()
{
    int a=2;

    printf("%d ",2>>32);
    printf("%d ",a>>32);

    a = (a>>32);
    printf("%d ", a);

}
//    printf("%d ", 2>>1);

/*    for (i=32; i>=1; --i)
    {
        a =    (a>>3);
    }
   
    printf("%d ", a);*/
输出结果:
图片附件: 游客没有浏览图片的权限,请 登录注册
呵呵。。。 最后的a依然是2   现在看到32就有点怪

最后测试过很多组数据  现象是  移位的实际位数 是 n%32   单纯的跑汇编也是一样

希望能有个人帮忙解释下

收到的鲜花
  • 霹雳键盘2011-04-20 19:42 送鲜花  3朵   附言:我很赞同
2011-04-20 08:57
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
移32位在 c++ 语言里是未定义的,rjsp 说的很清楚。原文是这样的:(节选自 ISO/IEC 14882:2003(E),第五章,第八节,第一条)
The operands shall be of integral or enumeration type and integral promotions are performed. The type of
the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or
greater than or equal to the length in bits of the promoted left operand.
(操作数应当是整型或枚举类型并且施用整型提升规则。结果的类型是提升后的左操作数的类型。当右操作是负数,或者大于等于提升后左操作数的位长度,行为是未定义的)

像楼主这种情况,因为 int 的位长是 32 位,而你右移了 32,即是 >= 32 的一个数,所以这种行为在标准里是未定义的。
不过这里 寒风 解释了 vc 的实现方法。有兴趣的也可以自己研究一下。


另过寒风问的那个问题,intel 手册里明确了(Intel(R) 64 and IA-32 Architectures Software Developer's Manual  - Volume 2B: Instruction Set Reference, N-Z):
The destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits
if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). A special opcode encoding is provided for a count of 1.
就注意那句 the count is masked to 5 bits,就是说 n%32。

直接写 (a << 4) 没有結果是因为,这种没有副作用的語句,如果忽略返回值,就会认为是空語句。


[ 本帖最后由 pangding 于 2011-4-20 10:30 编辑 ]
收到的鲜花
  • 霹雳键盘2011-04-20 19:43 送鲜花  3朵   附言:我很赞同
2011-04-20 10:25
快速回复:移位输出问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.042539 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved