是否有内置函数可以将数字转换为任意基数的字符串? [英] Is there a built-in function that converts a number to a string in any base?

查看:124
本文介绍了是否有内置函数可以将数字转换为任意基数的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想替换内部的match语句,并处理所有值,直到字母用完为止.我知道我可以自己写,但是我想使用内置函数.

I want to replace the inner match statement and work for all values up to when the alphabet runs out. I know I can write it myself, but I want to use built-in functions.

fn convert(inp: u32, out: u32, numb: &String) -> Result<String, String> {
    match isize::from_str_radix(numb, inp) {
        Ok(a) => match out {
            2 => Ok(format!("{:b}", a)),
            8 => Ok(format!("{:o}", a)),
            16 => Ok(format!("{:x}", a)),
            10 => Ok(format!("{}", a)),
            0 | 1 => Err(format!("No base lower than 2!")),
            _ => Err(format!("printing in this base is not supported")),
        },
        Err(e) => Err(format!(
            "Could not convert {} to a number in base {}.\n{:?}\n",
            numb, inp, e
        )),
    }
}

推荐答案

如果想提高性能,可以创建一个结构并为其实现DisplayDebug.这样可以避免分配String.为了最大程度地进行过度设计,您还可以使用堆栈分配的数组代替Vec.

If you wanted to eke out a little more performance, you can create a struct and implement Display or Debug for it. This avoids allocating a String. For maximum over-engineering, you can also have a stack-allocated array instead of the Vec.

此处是 Boiethios的答案,其中包含以下更改:

Here is Boiethios' answer with these changes applied:

struct Radix {
    x: i32,
    radix: u32,
}

impl Radix {
    fn new(x: i32, radix: u32) -> Result<Self, &'static str> {
        if radix < 2 || radix > 36 {
            Err("Unnsupported radix")
        } else {
            Ok(Self { x, radix })
        }
    }
}

use std::fmt;

impl fmt::Display for Radix {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut x = self.x;
        // Good for binary formatting of `u128`s
        let mut result = ['\0'; 128];
        let mut used = 0;
        let negative = x < 0;
        if negative {
            x*=-1;
        }
        let mut x = x as u32;
        loop {
            let m = x % self.radix;
            x /= self.radix;

            result[used] = std::char::from_digit(m, self.radix).unwrap();
            used += 1;

            if x == 0 {
                break;
            }
        }

        if negative {
            write!(f, "-")?;
        }

        for c in result[..used].iter().rev() {
            write!(f, "{}", c)?;
        }

        Ok(())
    }
}

fn main() {
    assert_eq!(Radix::new(1234, 10).to_string(), "1234");
    assert_eq!(Radix::new(1000, 10).to_string(), "1000");
    assert_eq!(Radix::new(0, 10).to_string(), "0");
}

仍然可以通过以下方式对其进行优化:

This could still be optimized by:

  • 创建ASCII数组而不是char数组
  • 不对数组进行零初始化

由于这些途径需要unsafe或类似 arraybuf 的外部包装箱,因此我没有将它们包括在内.您可以在

Since these avenues require unsafe or an external crate like arraybuf, I have not included them. You can see sample code in internal implementation details of the standard library.

这篇关于是否有内置函数可以将数字转换为任意基数的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆