C++中GMP库如何对mpz_class变量执行按位取反操作?
对mpz_class变量实现固定位数的按位取反
GMP的mpz_class是带符号的任意精度整数,直接用~运算符会对所有位(包括无穷多的高位符号位)取反,得到的结果是-num -1,这显然不是你想要的固定位数按位取反效果。要实现类似0b1110101变为0b0001010的效果,核心思路是用指定位数的全1掩码和原数做异或,具体分两种场景:
1. 已知要取反的位数
如果你明确知道目标二进制位数(比如示例中的7位),可以先生成对应位数的全1掩码,再通过异或操作实现每一位取反:
#include <gmpxx.h> #include <iostream> int main() { mpz_class num = 0b1110101; const unsigned int target_bits = 7; // 生成2^target_bits - 1的全1掩码(0b1111111) mpz_class mask; mpz_ui_pow_ui(mask.get_mpz_t(), 2, target_bits); mask -= 1; // 异或实现按位取反 num ^= mask; // 输出二进制结果 std::cout << num.get_str(2) << std::endl; // 输出0001010 return 0; }
2. 根据原数的有效二进制位数取反
如果不知道固定位数,想基于原数实际的二进制有效位数(去掉前导零后的位数)取反,可以用mpz_sizeinbase函数获取位数后再生成掩码:
#include <gmpxx.h> #include <iostream> int main() { mpz_class num = 0b1110101; // 获取原数的二进制有效位数(这里返回7) unsigned int bits = mpz_sizeinbase(num.get_mpz_t(), 2); // 生成对应位数的全1掩码 mpz_class mask; mpz_ui_pow_ui(mask.get_mpz_t(), 2, bits); mask -= 1; // 异或取反 num ^= mask; std::cout << num.get_str(2) << std::endl; // 输出0001010 return 0; }
注意事项
- 若原数为
0,mpz_sizeinbase返回1,取反后结果为1(0b1),符合预期; - 这种方式本质是对指定范围内的二进制位取反,而非所有位,这也是你要的"按位补码"效果(对应固定位数的无符号取反)。
内容的提问来源于stack exchange,提问作者asdasdqwer
相关产品推荐
相关产品推荐

