获取int类型的长度

  • 本文关键字:类型 int 获取 rust
  • 更新时间 :
  • 英文 :


我试图在rust中获得int的长度(以十进制解释时的位数)。我找到了一种方法来做到这一点,但是我正在寻找来自原始本身的方法。这是我的文件:

let num = 90.to_string();
println!("num: {}", num.chars().count())
// num: 2

我正在看https://docs.rs/digits/0.3.3/digits/struct.Digits.html#method.length。这是一个好的候选人吗?我如何使用它?还是有其他的板条箱可以帮我?

用更少的类型转换的一行是我正在寻找的理想解决方案。

您可以循环并检查在该数字变为个位数之前可以将其除以10的次数。或者在另一个方向上(因为除法比乘法慢),检查10*10*...*10相乘的频率,直到达到数字:

fn length(n: u32, base: u32) -> u32 {
let mut power = base;
let mut count = 1;
while n >= power {
count += 1;
if let Some(new_power) = power.checked_mul(base) {
power = new_power;
} else {
break;
}
}
count
}

从rust 1.67开始,可以使用:

n.checked_ilog10().unwrap_or(0) + 1

下面是不需要字符串或浮点数的一行代码:

println!("num: {}", successors(Some(n), |&n| (n >= 10).then(|| n / 10)).count());

它只是计算初始数除以10得到0的次数。


编辑:这个答案的第一个版本使用iterate来自(优秀和强烈推荐)itertoolscrate,但@trentcl指出successors来自stdlib做同样的事情。作为参考,下面是使用iterate的版本:

println!("num: {}", iterate(n, |&n| n / 10).take_while(|&n| n > 0).count().max(1));

这里有一个(几乎)比字符串转换更快的一行代码,使用std::iter:

let some_int = 9834;
let decimal_places = (0..).take_while(|i| 10u64.pow(*i) <= some_int).count();

下面的第一种方法依赖于以下公式,其中ab是对数底。

log<a>( x ) = log<b>( x ) / log<b>( a )
log<a>( x ) = log<2>( x ) / log<2>( a )  // Substituting 2 for `b`.

下面的函数可用于求2的幂的基数的位数。这种方法非常快。

fn num_digits_base_pow2(n: u64, b: u32) -> u32
{
(63 - n.leading_zeros()) / (31 - b.leading_zeros()) + 1
}

n(我们想要表示的数字)和b(基数)的位进行计数,以找到它们的log2下限值。然后,这些值的调整比率给出了期望基数中的天花板对数值。

对于查找任意进制的位数的通用方法,以下内容应该足够了。

fn num_digits(n: u64, b: u32) -> u32
{
(n as f64).log(b as f64).ceil() as u32
}

如果num已签名:

let digits = (num.abs() as f64 + 0.1).log10().ceil() as u32;

数字的一个很好的性质,总是很好记住的是,在进制$n$中写一个数字$x$所需的位数实际上是$lceil log_n(x + 1) rceil$。

因此,可以简单地编写以下函数(注意从u32f32的转换,因为整数没有日志函数):

fn length(n: u32, base: u32) -> u32 {
let n = (n+1) as f32;
n.log(base as f32).ceil() as u32
}

你可以很容易地将它用于负数。对于浮点数,这可能有点(即很多)更棘手。

考虑Daniel关于使用f32引入的病理情况的评论,请注意,在夜间Rust中,整数具有对数方法。(请注意,在我看来,这些都是实现的细节,你应该更多地关注于理解算法而不是实现。):

#![feature(int_log)]
fn length(n: u32, base: u32) -> u32 {
n.log(base) + 1
}

最新更新