13个版本 (4个重大更改)
0.5.1 | 2024年2月11日 |
---|---|
0.5.0 | 2024年2月9日 |
0.4.0 | 2024年2月8日 |
0.3.1 | 2024年2月8日 |
0.1.0 | 2024年1月23日 |
#429 in 算法
每月下载量78
用于 visu
89KB
946 行
count-digits
CountDigits 是一个不使用std的特质,包含用于确定各种数制下整数长度的函数。
它适用于所有原始整数类型以及所有非零整数类型。
pub trait CountDigits: Copy + Sized {
/// The type of integer that should be used for radix arguments.
type Radix;
/// Returns the count of bits in an integer.
fn count_bits(self) -> u32;
/// Returns the count of octal digits in an integer.
fn count_octal_digits(self) -> u32;
/// Returns the count of hexadecimal digits in an integer.
fn count_hex_digits(self) -> u32;
/// Returns the count of decimal digits in an integer.
fn count_digits(self) -> usize;
/// Returns the count of digits in an integer for a given radix.
/// Panics if the provided radix is invalid.
fn count_digits_radix(self, radix: Self::Radix) -> usize;
/// Returns the count of digits in an integer for a given radix.
/// Returns None if the given radix is invalid.
fn checked_count_digits_radix(self, radix: Self::Radix) -> Option<usize>;
}
示例
use count_digits::CountDigits;
// Base 2
assert_eq!(16, 0b1111000000001101.count_bits());
assert_eq!(16, 0b1111000000001101.count_digits_radix(2_u32));
// Base 8
assert_eq!(06, 0o170015.count_octal_digits());
assert_eq!(06, 0o170015.count_digits_radix(8_u32));
// Base 10
assert_eq!(05, 61453.count_digits());
assert_eq!(05, 61453.count_digits_radix(10_u32));
// Base 16
assert_eq!(04, 0xF00D.count_hex_digits());
assert_eq!(04, 0xF00D.count_digits_radix(16_u32));
返回u32的函数
名称函数,其中基数是2的幂,返回u32,以兼容Rust的位操作函数和常量。
assert_eq!(0b1011___u8.count_bits(), u8::BITS - 0b1011___u8.leading_zeros());
assert_eq!(0b1011__i32.count_bits(), i32::BITS - 0b1011__i32.leading_zeros());
assert_eq!(0b1011_u128.count_bits(), u128::BITS - 0b1011_u128.leading_zeros());
返回usize的函数
不是位操作上下文中固有意义的函数返回usize,以兼容Rust的格式化函数和宏。
let numbers = [2, 3, 13, 103, 1337];
let max_digits = numbers
.iter()
.map(CountDigits::count_digits)
.max()
.unwrap();
for n in numbers {
assert_eq!(4, format!("{n:>max_digits$}").chars().count());
}
在格式化二进制、八进制或十六进制数字时,可以使用count_digits_radix(2 | 8 | 16)和checked_count_digits_radix(2 | 8 | 16)函数代替count_bits()、count_octal_digits()和count_hex_digits(),直接以usize获取所需计数。
let numbers = [0b1, 0b10, 0b101, 0b1011];
let max_bits = numbers
.iter()
.map(|n| n.count_digits_radix(2u32))
.max()
.unwrap();
for n in numbers {
assert_eq!(4, format!("{n:>max_bits$}").chars().count());
}
无效的基数值
传递给count_digits_radix()和checked_count_digits_radix()的值必须大于或等于2。
- count_digits_radix() 如果给定一个无效的基数将 panic。
for n in 0..100 {
assert!(std::panic::catch_unwind(|| n.count_digits_radix(0_u32)).is_err());
assert!(std::panic::catch_unwind(|| n.count_digits_radix(1_u32)).is_err());
}
- checked_count_digits_radix() 如果给定一个无效的基数将返回 None。
for n in 0..100 {
assert!(n.checked_count_digits_radix(0_u32).is_none());
assert!(n.checked_count_digits_radix(1_u32).is_none());
}
负数
由于用十进制表示的负数会显示负号,所以正数的十进制位数将与该数的相反数的十进制位数相等,前提是没有发生卷绕。
请注意,负号本身不包括在计数中,因为负号不是一个数字。
assert_eq!(
867_5309_i32.count_digits(),
867_5309_i32.wrapping_neg().count_digits(),
);
用其他基数表示的负数的位数反映了 二进制补码 表示,正数的位数将 不 与其相反数的位数相同。
for radix in 2..=16 {
match radix {
10 => assert_eq!(
0xF00D_i32.count_digits_radix(radix),
0xF00D_i32.wrapping_neg().count_digits_radix(radix),
),
_ => assert_ne!(
0xBAD_i32.count_digits_radix(radix),
0xBAD_i32.wrapping_neg().count_digits_radix(radix),
),
}
}
这与 Rust 的显示格式一致。
// Base 2
assert_eq!(01, format!("{:b}", 1_i32).chars().count());
assert_eq!(32, format!("{:b}", -1_i32).chars().count());
// Base 8
assert_eq!(01, format!("{:o}", 1_i32).chars().count());
assert_eq!(11, format!("{:o}", -1_i32).chars().count());
// Base 10
assert_eq!(01, format!("{ }", 1_i32).chars().count());
assert_eq!(01, format!("{ }", -1_i32).strip_prefix('-').unwrap().chars().count());
// Base 16
assert_eq!(01, format!("{:x}", 1_i32).chars().count());
assert_eq!(08, format!("{:x}", -1_i32).chars().count());
基准测试
许可:MIT