MFC位移超过32位

发布于 2024-10-21 00:36:00 字数 466 浏览 2 评论 0原文

我目前在位移运算符方面遇到问题。我对此不熟悉,所以请原谅这个蹩脚的问题。

我有下面的代码:

INT iBitShift = 82;
INT iMaxColumn = 82;
for ( iCol = 0; iCol < iMaxColumn; iCol++ ) {
    dwColumnBit = (dwNewBitmap >> iBitShift) & 0x01;

    if ( dwColumnBit ) {
        // do something..
    }
    iBitShift--;
}

当 iMaxColumn 小于 30 时它工作正常,但当它变成 82 时,问题就开始了。发生的情况是,当 iCol 达到 32 和 64 时,dwColumnBit 不再获得正确的值。我的代码有什么问题吗?我读过有关循环移位的内容,但我不知道如何实现它。

提前致谢!

I'm currently having a problem with bitshift operators. I'm not familiar with it so pardon the lame question.

I have the following code below:

INT iBitShift = 82;
INT iMaxColumn = 82;
for ( iCol = 0; iCol < iMaxColumn; iCol++ ) {
    dwColumnBit = (dwNewBitmap >> iBitShift) & 0x01;

    if ( dwColumnBit ) {
        // do something..
    }
    iBitShift--;
}

It was working fine when the iMaxColumn was less than 30 but when it became 82, the problem started already. What happens is that when iCol reaches 32 and 64, the dwColumnBit no longer gets the correct value. Anything wrong in my code? I've read about circular shifts but I don't know how to implement it.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦途 2024-10-28 00:36:00

根据您的命名约定,我猜您正在尝试对 DWORD 执行位移位。 DWORD 是 4 个字节,这意味着 32 位(在 32 位机器中)。因此,当您将 DWORD 移位 32 次时,DWORD 中将全部为零。

此外,您的语句:

(dwNewBitmap >> iBitShift) & 0x01

尝试移动超过 32 位,因为 iBitShift 是用 82 初始化的,这意味着考虑到只有 32 位可以移动,它将无法移动 82 位。

我希望这能澄清您认为“奇怪”的行为。

编辑:基于OP中的一些信息在评论中:

看起来位图以二进制数据的形式存储在注册表中。您需要将该二进制数据读入字节数组,然后您可以分解逻辑,一次仅从该数据中选取一个 DWORD(在循环中执行此操作),然后在循环中从 1 开始检查该 DWORD 的位到 32。这样您就可以知道哪些位已设置,哪些位未设置。

From your naming conventions, I guess you are trying to perform bit shifts on a DWORD. A DWORD is 4 bytes which means 32 bits (in a 32-bit machine). So, when you have shifted a DWORD 32 times you will have all Zero's in the DWORD.

Furthermore, your statement:

(dwNewBitmap >> iBitShift) & 0x01

is trying to shift more than 32 bits since iBitShift is initialized with 82 which means that it will not be able to shift 82 bits considering that there are only 32 bits that can be shifted around.

I hope this clarifies the behavior that you find as 'strange'.

EDIT: Based on some information from OP In comments:

Looks like a bitmap is stored in the form of binary data in the registry. You need to read that binary data into a byte array and then you can break up your logic to pick only a DWORD from that data at a time (Do this in a loop) and then check the bits of that DWORD in a loop from 1 to 32. This way you will get to know that which bits are set and which aren't.

短暂陪伴 2024-10-28 00:36:00

当你跨越字边界移动时,你会丢失一些位。

看来您想知道 iBitShift 位的值。您可能需要首先找到正确的单词(使用iBitShift/wordsize),然后移动其余位(使用iBitShift%wordsize):

template< typename T, int N >
bool bit( T (&words)[N], int iIndex ) {
    static const size_t bitsperword = 
      sizeof(T)*numeric_limits<unsigned char>::digits;
    // find proper word (assuming words[0] contains the first word)
    T word = words[ iIndex/bitsperword ];
    // shift the residue
    word >>= iIndex%bitsperword;
    return word & 0x1;        
}

int main(){
  int ints [] = {1,~0x0};
  for( int i = 0; i != sizeof(int)*sizeof(ints); ++i ) {
    printf("%d", bit(ints,i) ? 1:0);
  }
  return 0;
}

When you're shifting across the word boundary, you will lose bits.

It appears you want to know the value of bit iBitShift. You may want to do that by first finding the proper word (using iBitShift/wordsize), and then shifting the rest of the bits (using iBitShift%wordsize):

template< typename T, int N >
bool bit( T (&words)[N], int iIndex ) {
    static const size_t bitsperword = 
      sizeof(T)*numeric_limits<unsigned char>::digits;
    // find proper word (assuming words[0] contains the first word)
    T word = words[ iIndex/bitsperword ];
    // shift the residue
    word >>= iIndex%bitsperword;
    return word & 0x1;        
}

int main(){
  int ints [] = {1,~0x0};
  for( int i = 0; i != sizeof(int)*sizeof(ints); ++i ) {
    printf("%d", bit(ints,i) ? 1:0);
  }
  return 0;
}
我不是你的备胎 2024-10-28 00:36:00

由于您最终承认您确实在这里进行位图处理,因此您还可以考虑使用 std::bitset<82> 来完成该任务。 bitset 也能够与string 相互转换。最重要的是,它可以与枚举一起使用!

enum column {
  colA, colB, ....
  , colMAX // keep this one last
};

bitset<colMAX> columnvisible;

columnvisible.set(colB);
columnvisible.reset(colA);

...
storeStringInRegistry( columnvisible.tostring() );

...
columnvisible = bitset<colMAX>( readStringFromRegistry() );

for( column c = colA; c != colMAX; ++c ) {
    if( columnvisible[c] ) displayColumn( c );
}

很好,不是吗?

Since you finally admitted you're really doing bitmap handling here, you may also consider using an std::bitset<82> for the task. The bitset is able to convert to and from string, too. On top of that, it works with enum's!

enum column {
  colA, colB, ....
  , colMAX // keep this one last
};

bitset<colMAX> columnvisible;

columnvisible.set(colB);
columnvisible.reset(colA);

...
storeStringInRegistry( columnvisible.tostring() );

...
columnvisible = bitset<colMAX>( readStringFromRegistry() );

for( column c = colA; c != colMAX; ++c ) {
    if( columnvisible[c] ) displayColumn( c );
}

Nice, not?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文