Как получить компактное, но без потерь строковое представление поплавка в Rust? - PullRequest
2 голосов
/ 17 января 2020

Как вариант Как я могу преобразовать число с плавающей точкой в ​​строку? , я ищу простой способ получить строковое представление числа с плавающей точкой, которое было бы кратким и без потерь. Например:

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 .

Есть ли способ создать строку без потерь и использовать экспоненциальную запись автоматически только тогда, когда это уместно?

Может ли такое преобразование быть распространено на все числа * 1032? * Типы?


Чтобы уточнить цель. Я в основном хочу то же самое, как строковое плавание работает в другом языке программирования, который разумно переходит от фиксированной точки к экспоненциальной нотации для получения точного, понятного человеку представления. Например, на 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

1 Ответ

2 голосов
/ 18 января 2020

Требование здесь немного расплывчато. Возможно, вы захотите попробовать ryu ящик , чтобы увидеть, соответствует ли он вашим потребностям:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...