右移>>奇怪的结果......为什么? [英] Right shift >> weird result... Why?

查看:58
本文介绍了右移>>奇怪的结果......为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,解决这个问题对每个人来说都是显而易见的,

但是......当然不可能是对的。


我我正在使用borland bcc32免费编译器编译


这段代码旨在识别

a中最重要的位给定元素的无符号长数。现在我意识到有可能

这是一种更有效的方法,如果你知道更好的方法请

让我知道。


然而,代码的效率既不在这里也不在那里,

点是奇怪的结果:


//两个数组unsigned longs

unsigned long twoULongs [2];


//初始移位金额

unsigned long rShift = 0;


//用最大值填充数组的最低元素

//可能的值

twoULongs [0] = 0xFFFFFFFF ;

twoULongs [1] = 0;


//当我们发现最重要的
位时,这个循环应该结束在

//存储位数的数组元素0

rShift

//(实际上,位位置+ 1)

while((twoULongs [0]>> rShift)!= 0)

{

//显示班次的值(用于调试目的)

cout<< (twoULongs [0]>> rShift)<< endl;

//因为我们还没有找到msb,下次再换一次

rShift ++;

//暂停程序,所以我们可以看到最新的调试

//目的

cin.get();

}


现在输出,因为twoULongs [0]倾向于0:


31,15,7,3,1,4294967295 !!!


哇!!我们只是回到最高可能未签名的

长!!!


那么为什么它在1之后没有达到0?


请评价我的愚蠢,如果你知道什么是错的,请告诉我

OK, the solution to this is probably blindingly obvious to everyone,
but... surely it can''t be right.

I am compiling with borland bcc32 free compiler

this piece of code is designed to identify the most significant bit in
a given element in an array of unsigned longs. Now I realise there may
be a more efficient way to do this, and if you know a better way please
let me know.

However, the efficieny of the code is neither here nor there, the
point is the weird result:

// an array of two unsigned longs
unsigned long twoULongs[2];

// initial amount to shift by
unsigned long rShift = 0;

// fill the lowest element of the array with its maximum
// possible value
twoULongs[0] = 0xFFFFFFFF;
twoULongs[1] = 0;

// this loop should end when we have discovered the most significant
bit in
// element 0 of the array storing the bit number in
rShift
// (actually, the bit position + 1)
while((twoULongs[0] >> rShift) != 0)
{
// Display the value of the shift (for debug purposes)
cout << (twoULongs[0] >> rShift) << endl;
// since we haven''t found the msb yet, shift by one more next time
rShift++;
// pause the program so we can see whats going on for debug
// purposes
cin.get();
}

Now the output, as twoULongs[0] tends towards 0 is:

31, 15, 7, 3, 1, 4294967295 !!!

Whoa!! we just ticked over back to the highest possible unsigned
long!!!

So why didn''t it hit 0 after 1?

please rate my idiocy, and if you know whats wrong, tell me

推荐答案

Mick_fae_Glesga写道:
Mick_fae_Glesga wrote:
好的,解决这个问题的方法对每个人来说都是显而易见的,
但是......当然不可能是对的。

我正在编译borland bcc32免费编译器

这段代码旨在识别无符号long数组中给定元素中最重要的位。现在我意识到
可能是一种更有效的方法,如果你知道更好的方式
请告诉我。

然而,代码的效率是无论是在这里还是在那里,
点都是奇怪的结果:

//两个无符号长的数组
无符号长的两个空文[2];
//初始移位量
无符号长rShift = 0;

//填充数组的最低元素及其最大值//可能值
twoULongs [0] = 0xFFFFFFFF;
twoULongs [1] = 0;

//当我们在
/中发现最重要的位时,这个循环应该结束/ data元素0存储位数在
rShift
//(实际上,位位置+ 1)
while((twoULongs [0]>> rShift)!= 0)
{
//显示班次的值(用于调试目的)
cout<< (twoULongs [0]>> rShift)<< endl;
//因为我们还没有找到msb,下次再换一次
rShift ++;
//暂停程序,这样我们就可以看到调试的进展情况了br /> //用途
cin.get();

现在输出,因为twoULongs [0]倾向于0:
31,15,7,3,1,4294967295 !!!

哇!!我们只是回到最高可能未签名的那个很长的时间!

那么为什么它在1之后没有打到0?

请评价我的白痴,如果你知道什么是错的,请告诉我
OK, the solution to this is probably blindingly obvious to everyone,
but... surely it can''t be right.

I am compiling with borland bcc32 free compiler

this piece of code is designed to identify the most significant bit in
a given element in an array of unsigned longs. Now I realise there
may be a more efficient way to do this, and if you know a better way
please let me know.

However, the efficieny of the code is neither here nor there, the
point is the weird result:

// an array of two unsigned longs
unsigned long twoULongs[2];

// initial amount to shift by
unsigned long rShift = 0;

// fill the lowest element of the array with its maximum
// possible value
twoULongs[0] = 0xFFFFFFFF;
twoULongs[1] = 0;

// this loop should end when we have discovered the most significant
bit in
// element 0 of the array storing the bit number in
rShift
// (actually, the bit position + 1)
while((twoULongs[0] >> rShift) != 0)
{
// Display the value of the shift (for debug purposes)
cout << (twoULongs[0] >> rShift) << endl;
// since we haven''t found the msb yet, shift by one more next time
rShift++;
// pause the program so we can see whats going on for debug
// purposes
cin.get();
}

Now the output, as twoULongs[0] tends towards 0 is:

31, 15, 7, 3, 1, 4294967295 !!!

Whoa!! we just ticked over back to the highest possible unsigned
long!!!

So why didn''t it hit 0 after 1?

please rate my idiocy, and if you know whats wrong, tell me




换位数字大于或等于位数左边

左边操作数导致未定义的行为。在英特尔处理器上,转换指令仅使用低6位,但C ++不能用这些术语来定义转换,所以它根本没有定义它。


所以,一旦rShift达到32,你根本就没有转变。或者你

可以收到一封讨厌的电子邮件。或者恶魔可以飞出你的鼻子。

V

-

请通过邮件回复我的地址删除资金/>



Shifting with the number larger or the same than the number of bits
in the left operand causes undefined behaviour. On Intel processors,
IIRC, shifting instruction only uses the lower 6 bits, but C++ cannot
define shifting in those terms, so it doesn''t define it at all.

So, as soon as rShift reaches 32, you get no shift at all. Or you
can get a nasty email. Or the demons can fly out of your nose.
V
--
Please remove capital As from my address when replying by mail


啊,好的,谢谢......我希望它会为零....


嗯,你知道吗?在这个数字中询问什么是最高集合

位?这样的命令存在吗?或者我必须分别看每个位的


Ah, OK, thanks... I was hoping it would be zero....

Well, do you know of any other way of asking ''What is the highest set
bit in this number?'' does such a command exist? or do I have to look
at each bit individually?


Mick_fae_Glesga写道:
Mick_fae_Glesga wrote:
OK对于每个人来说,解决这个问题的方法可能非常明显,但是......当然不可能是正确的。

我正在使用borland bcc32免费编译器进行编译
<这段代码旨在识别无符号长整数数组中给定元素中最重要的位。现在我意识到可能有更好的方法来做到这一点,如果你知道一个更好的方法请
让我知道。

然而,代码的效率是无论是在这里还是在那里,
点都是奇怪的结果:

//两个无符号长的数组
无符号长的两个空文[2];
//初始移位量
无符号长rShift = 0;

//填充数组的最低元素及其最大值//可能值
twoULongs [0] = 0xFFFFFFFF;
twoULongs [1] = 0;

//当我们在
/中发现最重要的位时,这个循环应该结束/ data元素0存储位数在
rShift
//(实际上,位位置+ 1)
while((twoULongs [0]>> rShift)!= 0)
{
//显示班次的值(用于调试目的)
cout<< (twoULongs [0]>> rShift)<< endl;
//因为我们还没有找到msb,下次再换一次
rShift ++;
//暂停程序,这样我们就可以看到调试的进展情况了br /> //用途
cin.get();

现在输出,因为twoULongs [0]倾向于0:
31,15,7,3,1,4294967295 !!!

哇!!我们只是回到最高可能未签名的那个很长的时间!

那么为什么它在1之后没有打到0?

请评价我的白痴,如果你知道什么不对,请告诉我
OK, the solution to this is probably blindingly obvious to everyone,
but... surely it can''t be right.

I am compiling with borland bcc32 free compiler

this piece of code is designed to identify the most significant bit in
a given element in an array of unsigned longs. Now I realise there may
be a more efficient way to do this, and if you know a better way please
let me know.

However, the efficieny of the code is neither here nor there, the
point is the weird result:

// an array of two unsigned longs
unsigned long twoULongs[2];

// initial amount to shift by
unsigned long rShift = 0;

// fill the lowest element of the array with its maximum
// possible value
twoULongs[0] = 0xFFFFFFFF;
twoULongs[1] = 0;

// this loop should end when we have discovered the most significant
bit in
// element 0 of the array storing the bit number in
rShift
// (actually, the bit position + 1)
while((twoULongs[0] >> rShift) != 0)
{
// Display the value of the shift (for debug purposes)
cout << (twoULongs[0] >> rShift) << endl;
// since we haven''t found the msb yet, shift by one more next time
rShift++;
// pause the program so we can see whats going on for debug
// purposes
cin.get();
}

Now the output, as twoULongs[0] tends towards 0 is:

31, 15, 7, 3, 1, 4294967295 !!!

Whoa!! we just ticked over back to the highest possible unsigned
long!!!

So why didn''t it hit 0 after 1?

please rate my idiocy, and if you know whats wrong, tell me




问题是op>>的结果当

上的值大于或等于左边的位数时,未定义。

或者标准(5.8.1)将其放置:


"如果右操作数为负数或更高,则行为未定义

大于或等于提升左操作数的位长度。 ;


"未定义的行为"是最糟糕的一种,因为我们确实不知道在这种情况下会发生什么。该程序可能会结束,你的硬盘驱动器可能会被删除,该程序完全可以自由地做你想做的任何事情。


我们想要成为能够说,哦,你的编译器显然正在做

''a>> (b%32)'',但除非你的编译器专门告诉你这个,否则我们没有理由这么认为。即使它确实如此,你可能也不会依赖它,因为如果你切换编译器,你的代码可能会停止工作。


你要做的就是问自己,我想在这个

的情况下发生什么?,然后编写你的代码来明确地做到这一点。对于

实例,如果你希望你的代码在右移多少个地方时生成零,你必须明确说:


unsigned long v = 0;


if(rShift> = numberOfBitsInAnUL)

v = 0;

else

v = twoULongs [0]>> rShift;


//使用v代替twoULongs [0]>> rShift。

简单地说,任何其他行动都是疯狂的。

Jack Saalweachter



The problem is that the result of op >> is undefined when the value on
the right is greater than or equal to the number of bits on the left.
Or as the Standard (5.8.1) puts it:

"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."

"Undefined behavior" is the worst kind, because we literally don''t know
what happens in that case. The program could end, your hard-drive could
be deleted, the program is quite literally free to do whatever you want.

WE WOULD LIKE to be able to say, "Oh, your compiler is obviously doing
''a >> (b % 32)''," but unless your compiler specifically tells you this,
we have no reason to think so. Even if it did say so, you probably
shouldn''t rely on it, because if you switch compilers, your code could
stop working.

What you have to do is ask yourself, "What do I want to happen in this
situation?", and then write your code to explicitly do this. For
instance, if you want your code to produce zeros when you right-shift by
too many places, your must explicitly say:

unsigned long v = 0;

if (rShift >= numberOfBitsInAnUL)
v = 0;
else
v = twoULongs[0] >> rShift;

// work with v instead of twoULongs[0] >> rShift.
Simply put, any other course of action is madness.
Jack Saalweachter


这篇关于右移&gt;&gt;奇怪的结果......为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆