问题描述
我最近使用右移运营商面临着一个奇怪的行为。
以下程序:
的#include< cstdio>
#包括LT&; cstdlib>
#包括LT&;&iostream的GT;
#包括LT&;&stdint.h GT;INT美孚(INT A,INT B)
{
返回>> b:
}INT栏(uint64_t中A,INT B)
{
返回>> b:
}INT主(INT ARGC,字符** argv的)
{
性病::法院LT&;< 富(1,32):<<富(1,32)所述;&下;的std :: ENDL;
性病::法院LT&;< 酒吧(1,32):<<杆(1,32)所述;&下;的std :: ENDL;
性病::法院LT&;< 1>> 32:&所述;&下; (1 GT;> 32)&所述;&下;的std :: ENDL; //这里的警告
性病::法院LT&;< (int)的1 GT;>(INT)32:&所述;&下; ((int)的1 GT;>(int)的32)所述;&下;的std :: ENDL; //这里的警告 返回EXIT_SUCCESS;
}
输出:
富(1,32):1 //应该是0(但我想我想的东西)
杆(1,32):0
1>> 32:0
(int)的1 GT;> (INT)32:0
与富()
功能会发生什么?据我了解,之间它做什么,最后2行,唯一的区别是,最后两行是在编译时进行评估。为什么它会携手如果我使用一个64位的整数?
对此的灯光,将大大AP preciated!
当然有关,这里是 G ++
给出:
> G ++ -o测试TEST.CPP
TEST.CPP:在函数'主INT(INT,CHAR **):
TEST.CPP:20:36:警告:右移计数> =类型的宽度
TEST.CPP:21:56:警告:右移计数> =类型的宽度
这是有可能的的 CPU 的实际计算
A>> (二%32)
在富
;同时,1 >> 32是一个常数前pression,所以的编译的将折叠不断在编译时,莫名其妙地给了0。
由于标准(C ++ 98派5.8 / 1)指出,
there is no contradiction having foo(1,32)
and 1>>32
giving different results.
On the other hand, in bar
you provided a 64-bit unsigned value, as 64 > 32 it is guaranteed the result must be 1 / 2 = 0. Nevertheless, if you write
bar(1, 64);
you may still get 1.
Edit: The logical right shift (SHR) behaves like a >> (b % 32/64)
on x86/x86-64 (Intel #253667, Page 4-404):
However, on ARM (armv6&7, at least), the logical right-shift (LSR) is implemented as (ARMISA Page A2-6)
(bits(N), bit) LSR_C(bits(N) x, integer shift)
assert shift > 0;
extended_x = ZeroExtend(x, shift+N);
result = extended_x<shift+N-1:shift>;
carry_out = extended_x<shift-1>;
return (result, carry_out);
where (ARMISA Page AppxB-13)
ZeroExtend(x,i) = Replicate('0', i-Len(x)) : x
This guarantees a right shift of ≥32 will produce zero. For example, when this code is run on the iPhone, foo(1,32)
will give 0.
These shows shifting a 32-bit integer by ≥32 is non-portable.
这篇关于向右移位运算符的怪异的行为(1&GT;&GT; 32)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!