奇怪的位移算子 [英] Strange Bit Shift Operator
问题描述
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屋!