其中LSB在索引0处且MSB在索引63处。同样,它应该扩展到u32和其他类型。
let my_num: u64 = 100; // 0b1100100 let msb = get_msb(my_num); // 0 let lsb = get_lsb(my_num); // 0
字符串更正:MSB在第63位应为0,而不是索引6处的1
nue99wik1#
正如注解中所解释的,您可以分别使用n & 1和(n >> 63) & 1获得u64的LSB和MSB。不过,在Rust中完全泛型化是一个麻烦,因为泛型需要像移位、掩码甚至是1的构造这样的操作来预先完全指定。然而,这就是num-traits crate来拯救的地方。与它的表亲num一起,它是数字领域通用Rust的事实上的标准,提供了(除其他外)PrimInt特征,使get_msb()和get_lsb()变得简单:
n & 1
(n >> 63) & 1
u64
1
num-traits
num
PrimInt
get_msb()
get_lsb()
use num_traits::PrimInt; pub fn get_lsb<N: PrimInt>(n: N) -> N { n & N::one() } pub fn get_msb<N: PrimInt>(n: N) -> N { let shift = std::mem::size_of::<N>() * 8 - 1; (n >> shift) & N::one() } fn main() { assert_eq!(get_lsb(100u32), 0); assert_eq!(get_lsb(101u32), 1); assert_eq!(get_msb(100u32), 0); assert_eq!(get_msb(u32::MAX), 1); }
字符串Playground的1如果你对只使用标准库的完整版本感到好奇,下面是它的样子:
use std::convert::TryFrom; use std::ops::{BitAnd, Shr}; fn one<N: TryFrom<u8>>() -> N { 1u8.try_into().unwrap_or_else(|_| unreachable!()) } pub fn get_lsb<N>(n: N) -> N where N: BitAnd<Output = N> + TryFrom<u8>, { n & one() } pub fn get_msb<N>(n: N) -> N where N: Shr<usize, Output = N> + BitAnd<Output = N> + TryFrom<u8>, { let shift = std::mem::size_of::<N>() * 8 - 1; (n >> shift) & one() }
型Playground的
1条答案
按热度按时间nue99wik1#
正如注解中所解释的,您可以分别使用
n & 1
和(n >> 63) & 1
获得u64
的LSB和MSB。不过,在Rust中完全泛型化是一个麻烦,因为泛型需要像移位、掩码甚至是
1
的构造这样的操作来预先完全指定。然而,这就是num-traits
crate来拯救的地方。与它的表亲num
一起,它是数字领域通用Rust的事实上的标准,提供了(除其他外)PrimInt
特征,使get_msb()
和get_lsb()
变得简单:字符串
Playground的
1如果你对只使用标准库的完整版本感到好奇,下面是它的样子:
型
Playground的