【问题标题】:How to get a compact but lossless string representation of a float in Rust?如何在 Rust 中获得一个紧凑但无损的浮点字符串表示?
【发布时间】:2020-05-04 17:39:26
【问题描述】:

作为How can I convert a float to string? 的变体,我正在寻找一种简单的方法来获取既简洁又无损的浮点字符串表示。例如:

let a = 1.0;
let b = 1.1234567890123456789012345678901e50;
let c = 1.1234567890123456789012345678901e-50;
for x in &[a, b, c] {
    println!("{}", x);
    println!("{:?}", x);
    println!("{}", x.to_string());
    println!("{}", f64::to_string(&x));
    println!("{:e}", x);
}

这会产生:

1
1.0
1
1
1e0
112345678901234570000000000000000000000000000000000
112345678901234570000000000000000000000000000000000.0
112345678901234570000000000000000000000000000000000
112345678901234570000000000000000000000000000000000
1.1234567890123457e50
0.000000000000000000000000000000000000000000000000011234567890123456
0.000000000000000000000000000000000000000000000000011234567890123456
0.000000000000000000000000000000000000000000000000011234567890123456
0.000000000000000000000000000000000000000000000000011234567890123456
1.1234567890123456e-50

换句话说:

  • {}{:?}x.to_string()f64::to_string(&x) 都会产生许多前导/尾随零。
  • {:e} 有助于打印 bc,但它对所有数字强制使用指数符号,这会导致像 1e0 这样的异常表示。

有没有办法产生一个无损的字符串,并且只有在适当的时候才自动使用指数表示法?

这种转换是否可以通用地扩展到所有数字类型?


明确目标。我基本上希望字符串化浮点数在其他编程语言中的工作方式相同,这些编程语言巧妙地从定点符号变为指数符号以产生精确的、人类可读的表示。例如在 JVM 上:

scala> (1.1234567890123456789012345678901e50).toString()
res1: String = 1.1234567890123457E50

scala> (1.0).toString()
res2: String = 1.0

scala> (1.1234567890123456789012345678901e-50).toString()
res3: String = 1.1234567890123456E-50

【问题讨论】:

  • "{}" 使用Displayx.to_string() 也使用f64::to_string,所以这三个东西其实是一回事。
  • @Shepmaster 我不应该说“紧凑”,也许更好的词是“人性化”。例如,人类很可能更喜欢1 而不是1e0e50 后缀,而不是拼出很多零。在 CS 中是否有更好的术语来表示这种“人类标准化”?
  • float 必须像物理中的真实一样被操纵,首先你要学习的是计算重要的数字,float 与你的工作没有区别,你知道你在操纵什么,因此知道你可以信任什么。如果您的计算允许 5 个数字精度显示 5 个数字精度等。

标签: string rust


【解决方案1】:

这里的要求有点模糊。您可能想试试ryu crate 看看它是否符合您的需求:

use ryu;  // ryu = "1.0"

fn main() {
    let mut buffer = ryu::Buffer::new();
    let a = 1.0;
    let b = 1.1234567890123456789012345678901e50;
    let c = 1.1234567890123456789012345678901e-50;
    for &x in [a, b, c].iter() {
        println!("{}", buffer.format(x));
    }
}

它产生输出:

1.0
1.1234567890123457e50
1.1234567890123456e-50

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-19
    • 2020-11-13
    • 1970-01-01
    • 2021-07-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多