奇怪的位移算子 [英] Strange Bit Shift Operator

查看:94
本文介绍了奇怪的位移算子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello group,


我正在使用压缩工具,在VC ++ 6.0编译器上看到这个令人费解的一点。/ b
行为。


#include< iostream>

使用命名空间std;

typedef unsigned char uchar;

#定义NBITS(x)((uchar)(~0u<< sizeof(0u)* 8-(x)>> sizeof(0u)* 8-(x)))

/ / NBITS形成一个包含指定位数的字节。

void main()

{int k = 0;

cout<< ; hex<<(int)NBITS(k)<< endl;

cout<< hex<<(int)NBITS(0)<< endl;

}

/ ****输出*** /

ff

00

/ ****输出结束*** /


有趣的是,我得到两个不同的值用于相同的输入。我好b / b
真的不知道是什么导致它,但我有一个huntch,

预处理器正在计算(对于常数值0)值

不同的方式然后由编译器生成的代码(在运行时使用的是
)。


提前谢谢,
< br $>
----

VJ

解决方案



vj写道:

Hello group,

我正在研究一个压缩工具,在VC ++ 6.0编译器上看到这个令人费解的一点点行为。

#include< iostream>
使用命名空间std;
typedef unsigned char uchar;
#define NBITS(x)((uchar)(〜0u< < sizeof(0u)* 8-(x)>> sizeof(0u)* 8-(x)))
// NBITS形成一个包含指定位数的字节。
void main()
{int k = 0;
cout<< hex<<(int)NBITS(k)<< endl;
cout<< hex<< ;(int)NBITS(0)<<输出结果*** /
ff
00
/ ****输出结束*** /




我会消除宏,这是一团糟。只需使用一个数组:


const unsigned char nBits [] =

{0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF };


并用nBits [k]替换NBITS(k)。


Greg


vj写道:

Hello group,
#include< iostream>
using namespace std;
typedef unsigned char uchar;
#define NBITS(x)((uchar)(〜0u<< sizeof(0u)* 8-(x)>> sizeof(0u)* 8-(x)))
/ / NBITS形成一个包含指定位数的字节。
void main()
{int k = 0;
cout<< hex<<(int)NBITS(k) << endl;
cout<< hex<<(int)NBITS(0)<< endl;
}
/ ****输出*** /
ff
00
/ ****输出结束*** /

有趣的是,我为同一输入获得了两个不同的值。我真的不知道是什么导致它,但我有一个huntch,
预处理器正在计算(对于常数值0)值不同的方式然后由编译器生成的代码(在运行时使用




5.8p1:关于移位运算符:

行为未定义如果右操作数是负数,或者更大

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


这里,因为sizeof(0u)* 8 =〜0u中的位数,它是未定义的

行为。换句话说,任何事情都可能发生,并且没有必要进行诊断。


vj写道:

我正在研究压缩工具,并在VC ++ 6.0编译器上看到了这个令人费解的行为。


在VC ++ v7.1中也是如此,可能还有很多其他编译器。

#include< iostream>
使用命名空间std;
typedef unsigned char uchar;
#define NBITS(x)((uchar)(〜0u<< sizeof(0u)* 8-(x)>> sizeof(0u)* 8-(x)))


该宏假设一个字节是8位。危险。

// NBITS形成一个包含指定位数的字节。
void main()


int main()

{int k = 0;
cout<< hex<<(int)NBITS(k)<< endl;
cout<< hex<<( int)NBITS(0)<< endl;
}
/ ****输出*** /
ff
00


我得到一个0.你怎么得到两个零?

/ ****输出结束*** /

有趣的是我得到两个不同的值对于相同的输入。我真的不知道是什么导致它,但我有一个huntch,
预处理器正在计算(对于常数值0)值不同的方式然后由编译器生成的代码(这是在运行时使用的。)




是的。对于常数0,结果在编译时计算,并且它是

正确。 不正确的在运行期间计算结果,并且它b / b $ b $涉及移位所有位设置。左边的值为32次,这与

完全没有相同。表达式''sizeof(0u)* 8 - k''

产生32,然后应用左移(32%32)。


这是一个固定的宏:


#define NBITS(x)((unsigned char)〜(~0u<<(x%8)))


除了做正确的事情,它只评估''x''一次,这通常是重要的。


V


Hello group,

I am working on a compression tool and saw this puzzling bit shit
behaviour on a VC++6.0 compiler.

#include <iostream>
using namespace std;
typedef unsigned char uchar;
#define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x)))
// NBITS forms a byte containing specified number of bits turned on.
void main()
{ int k=0;
cout<<hex<<(int) NBITS(k)<<endl;
cout<<hex<<(int) NBITS(0)<<endl;
}
/****output***/
ff
00
/****output ends***/

intrestingly i am getting two diffrent values for the same input. I
really dont know whats causing it, but i have a huntch that the
Preprocessor is calculating(for the constant value 0) the values
diffrent way then the code that generated by the compiler ( which is
used at the run time).

Thanks in advance,

----
VJ

解决方案


vj wrote:

Hello group,

I am working on a compression tool and saw this puzzling bit shit
behaviour on a VC++6.0 compiler.

#include <iostream>
using namespace std;
typedef unsigned char uchar;
#define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x)))
// NBITS forms a byte containing specified number of bits turned on.
void main()
{ int k=0;
cout<<hex<<(int) NBITS(k)<<endl;
cout<<hex<<(int) NBITS(0)<<endl;
}
/****output***/
ff
00
/****output ends***/



I would eliminate the macro, it''s a mess. Just use an array:

const unsigned char nBits[] =
{ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };

and replace NBITS(k) with nBits[k].

Greg


vj wrote:

Hello group, #include <iostream>
using namespace std;
typedef unsigned char uchar;
#define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x)))
// NBITS forms a byte containing specified number of bits turned on.
void main()
{ int k=0;
cout<<hex<<(int) NBITS(k)<<endl;
cout<<hex<<(int) NBITS(0)<<endl;
}
/****output***/
ff
00
/****output ends***/

intrestingly i am getting two diffrent values for the same input. I
really dont know whats causing it, but i have a huntch that the
Preprocessor is calculating(for the constant value 0) the values
diffrent way then the code that generated by the compiler ( which is
used at the run time).



5.8p1 : About shift operators :
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.

Here, since sizeof(0u) * 8 = number of bits in ~0u, it is "undefined
behaviour". In other words, anything may happen and no diagnosis is
necessary.


vj wrote:

I am working on a compression tool and saw this puzzling bit shit
behaviour on a VC++6.0 compiler.
It''s the same in VC++ v7.1, and probably many other compilers.
#include <iostream>
using namespace std;
typedef unsigned char uchar;
#define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x)))
This macro assumes that a byte is 8 bits. Dangerous.
// NBITS forms a byte containing specified number of bits turned on.
void main()
int main()
{ int k=0;
cout<<hex<<(int) NBITS(k)<<endl;
cout<<hex<<(int) NBITS(0)<<endl;
}
/****output***/
ff
00
I get a single 0. How do you get two zeros?
/****output ends***/

intrestingly i am getting two diffrent values for the same input. I
really dont know whats causing it, but i have a huntch that the
Preprocessor is calculating(for the constant value 0) the values
diffrent way then the code that generated by the compiler ( which is
used at the run time).



Yes. For a constant 0 the result is calculated in compile-time, and it is
"correct". The "incorrect" result is calculated during run-time, and it
involves shifting of "all bits set" value to the left 32 times, which is
the same as not shifting it at all. The expression ''sizeof(0u)*8 - k''
yields 32, then the left shift of (32 % 32) is applied.

Here is a fixed macro:

#define NBITS(x) ((unsigned char)~(~0u << (x % 8)))

Besides doing the right thing it evaluates ''x'' only once, which is often
important.

V


这篇关于奇怪的位移算子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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