use num_bigint::BigUint;
use num_traits::identities::One;
fn main() {
// Example: 10001 (17) => 1110 (14)
let n = BigUint::from(17u32);
println!("{}", n);
// BigUint doesn't support `!`
//let n = !n;
let mask = (BigUint::one() << n.bits()) - 1u32;
let n = n ^ mask;
println!("{}", n);
}
上面的代码使用位掩码对BigUint
进行二进制补码.问题:
- 有没有比掩码更好的二进制补码方法?似乎
BigUint
不包括!
运算符(但掩码可能无论如何都是必需的,这取决于!
是如何定义的). - 如果没有,有没有更好的方法来生成掩码?(缓存掩码很有帮助,但会占用大量内存.)
关于我实际看到的问题的更多背景:binary complement sequences
如果你交替地乘以3和位翻转一个数字,就会出现一些有趣的序列.以3开头的示例:
0. 3 (11b) => 3*3 = 9 (1001b) => bit complement is 6 (0110b)
1. 6 (110b)
2. 13 (1101b)
3. 24 (11000b)
4. 55 (110111b)
5. 90 (1011010b)
6. 241 (11110001b)
7. 300 (100101100b)
8. 123 (1111011b)
9. 142 (10001110b)
11. 85 (1010101b)
12. 0 (0b)
一个问题是,对于所有的起始数字,它是否都为零.有些人在达到零之前徘徊了很长一段时间(425720需要87,037,147,316次迭代才能达到0).能够有效地计算这一点有助于回答这些问题.不过,大多数情况下,我还是学到了一些Rust 的东西.