按位运算符 - 在特定位置获取单个十六进制数 (0-15)
bitwise operators - get single hex number (0-15) at certain position
假设我们有十六进制数
x = 0x345ABC678
如何获得给定位置的单个十六进制数字 (0-15) >> 仅使用按位运算符<< ?
例如我想从十六进制数中得到第 4 个数字 (0xA
) 或第 6 个数字 (0xC
)。
长话短说,我想通过大型单词数据库进行强力循环,我将它们转换为 64 位数字(而不是字符串),例如单词 "PUZZLER" 是一个数字 29996611546。 A 是 1,Z 是 33。所以我想从 int 29996611546 中获取第三个字母(存储为十进制 1-33)。如果你能向我解释如何处理十六进制,我可以在我的脚本中使用它。
我是一个简单的PHP程序员,所以我已经很久没有使用按位运算符了,希望你能帮助我。
你可以从
这样的东西开始
(x >> ((8 - i) * 4)) & 0xf
这对数字从左到右编号,1-8。
解释它是如何工作的:考虑示例 0x45ABC678
。假设我们想要第三位数字。我们想使用 >>
运算符将数字右移,然后取下最后一位。在这种情况下,我们想将它向右移动 5 个十六进制数字(即 5*4 = 20 位),丢掉 BC678
并留下 0x45A
。然后,当我们使用 0xf
按位与选择最后一个数字时,我们得到最后一个数字 0xA
.
要获得第一位数字,我们必须移动 7 位数字。要获得第三位数字,我们必须移动 5 位数字。要获得第 8 位数字,我们必须移动 0 位数字。 8 - i
给了我们那个模式。
Steve Summit 的 solution/explanation 很清楚。
或者,可以使用可变位掩码将 64 位数字拆分为 16 个十六进制数字。然后可以省略前导零以仅显示有意义的数字。
#include <iostream>
int main()
{
using namespace std;
typedef unsigned long long u64;
u64 number = 0x345ABC678;
int digits[16] = {0};
for( int i = 0; i < 16; i++ ) // fill in all 16 digits, incl. possible leading zero.
{
int shift_bits = 64 - 4 * ( i + 1 );
u64 mask = 0xFULL << shift_bits;
digits[i] = ( number & mask ) >> shift_bits;
}
int j = 0;
while( !digits[j] ){ j++; } // find the first index with non-zero digit.
cout << hex << uppercase;
cout << "digit #4 = " << hex << digits[ j + 3 ] << endl;
cout << "digit #6 = " << hex << digits[ j + 5 ] << endl;
}
结果:
digit #4 = A
digit #6 = C
假设我们有十六进制数
x = 0x345ABC678
如何获得给定位置的单个十六进制数字 (0-15) >> 仅使用按位运算符<< ?
例如我想从十六进制数中得到第 4 个数字 (0xA
) 或第 6 个数字 (0xC
)。
长话短说,我想通过大型单词数据库进行强力循环,我将它们转换为 64 位数字(而不是字符串),例如单词 "PUZZLER" 是一个数字 29996611546。 A 是 1,Z 是 33。所以我想从 int 29996611546 中获取第三个字母(存储为十进制 1-33)。如果你能向我解释如何处理十六进制,我可以在我的脚本中使用它。
我是一个简单的PHP程序员,所以我已经很久没有使用按位运算符了,希望你能帮助我。
你可以从
这样的东西开始(x >> ((8 - i) * 4)) & 0xf
这对数字从左到右编号,1-8。
解释它是如何工作的:考虑示例 0x45ABC678
。假设我们想要第三位数字。我们想使用 >>
运算符将数字右移,然后取下最后一位。在这种情况下,我们想将它向右移动 5 个十六进制数字(即 5*4 = 20 位),丢掉 BC678
并留下 0x45A
。然后,当我们使用 0xf
按位与选择最后一个数字时,我们得到最后一个数字 0xA
.
要获得第一位数字,我们必须移动 7 位数字。要获得第三位数字,我们必须移动 5 位数字。要获得第 8 位数字,我们必须移动 0 位数字。 8 - i
给了我们那个模式。
Steve Summit 的 solution/explanation 很清楚。
或者,可以使用可变位掩码将 64 位数字拆分为 16 个十六进制数字。然后可以省略前导零以仅显示有意义的数字。
#include <iostream>
int main()
{
using namespace std;
typedef unsigned long long u64;
u64 number = 0x345ABC678;
int digits[16] = {0};
for( int i = 0; i < 16; i++ ) // fill in all 16 digits, incl. possible leading zero.
{
int shift_bits = 64 - 4 * ( i + 1 );
u64 mask = 0xFULL << shift_bits;
digits[i] = ( number & mask ) >> shift_bits;
}
int j = 0;
while( !digits[j] ){ j++; } // find the first index with non-zero digit.
cout << hex << uppercase;
cout << "digit #4 = " << hex << digits[ j + 3 ] << endl;
cout << "digit #6 = " << hex << digits[ j + 5 ] << endl;
}
结果:
digit #4 = A
digit #6 = C