【发布时间】: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}有助于打印b和c,但它对所有数字强制使用指数符号,这会导致像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
【问题讨论】:
-
"{}"使用Display,x.to_string()也使用f64::to_string,所以这三个东西其实是一回事。 -
@Shepmaster 我不应该说“紧凑”,也许更好的词是“人性化”。例如,人类很可能更喜欢
1而不是1e0和e50后缀,而不是拼出很多零。在 CS 中是否有更好的术语来表示这种“人类标准化”? -
float 必须像物理中的真实一样被操纵,首先你要学习的是计算重要的数字,float 与你的工作没有区别,你知道你在操纵什么,因此知道你可以信任什么。如果您的计算允许 5 个数字精度显示 5 个数字精度等。