【问题标题】:How do I print a Rust floating-point number with all available precision?如何打印具有所有可用精度的 Rust 浮点数?
【发布时间】:2014-10-26 19:18:30
【问题描述】:

我正在为sin 三角函数实现 CORDIC 算法。为了做到这一点,我需要硬编码/计算一堆反正切值。现在我的函数似乎可以工作(由 Wolfram Alpha 验证)到打印的精度,但我希望能够打印我的f32 的所有 32 位精度。我该怎么做?

fn generate_table() {
    let pi: f32 = 3.1415926536897932384626;
    let k1: f32 = 0.6072529350088812561694; // 1/k
    let num_bits: uint = 32;
    let num_elms: uint = num_bits;
    let mul: uint = 1 << (num_bits - 2);

    println!("Cordic sin in rust");
    println!("num bits {}", num_bits);
    println!("pi is {}", pi);
    println!("k1 is {}", k1);

    let shift: f32 = 2.0;
    for ii in range(0, num_bits) {
        let ipow: f32 = 1.0 / shift.powi(ii as i32);
        let cur: f32 = ipow.atan();
        println!("table values {}", cur);
    }
}

【问题讨论】:

    标签: formatting rust cordic


    【解决方案1】:

    使用precision format specifier. 后跟您希望看到的精度小数位数:

    fn main() {
        let pi: f32 = 3.1415926536897932384626;
        let k1: f32 = 0.6072529350088812561694; // 1/k
    
        println!("pi is {:.32}", pi);
        println!("k1 is {:.32}", k1);
    }
    

    我选择了 32,这比f32s 中的小数位数

    pi is 3.14159274101257324218750000000000
    k1 is 0.60725295543670654296875000000000
    

    请注意,这些值不再匹配; floating point values are difficult!正如评论中提到的,您不妨print as hexadecimal or even use your literals as hexadecimal

    【讨论】:

    • 此答案不适用于小数字(除非您根据数字的大小调整格式语句。:(
    • 您需要我认为 51 的精度来获取所有f32 的所有数字,然后您需要修剪尾随0尾随.的。
    【解决方案2】:

    使用精度格式说明符是正确答案,但要打印所有可用精度,只需避免指定要显示的位数:

    // prints 1
    println!("{:.}", 1_f64);
    
    // prints 0.000000000000000000000000123
    println!("{:.}", 0.000000000000000000000000123_f64); 
    

    这样,您不会截断值,也不必修剪多余的零,并且所有值的显示都是正确的,无论它们是非常大还是非常小。

    Playground example

    为了完整起见,精度格式说明符还支持指定固定精度(根据接受的答案):

    // prints 1.0000
    println!("{:.4}", 1_f64);
    

    以及在运行时指定的精度(当然不必是const):

    // prints 1.00
    const PRECISION: usize = 2;
    println!("{:.*}", PRECISION, 1_f64); // precision specifier immediately precedes positional argument
    

    【讨论】:

      【解决方案3】:

      此答案是为 Rust 0.12.0 编写的,不适用于 Rust 1.x。


      您可以在std::f32 中使用to_string 函数(不要与to_string 方法混淆):

      fn main() {
          println!("{}", std::f32::to_string(unsafe { std::mem::transmute::<i32, f32>(1) }));
          println!("{}", std::f32::to_string(unsafe { std::mem::transmute::<i32, f32>(16) }));
          println!("{}", std::f32::to_string(std::f32::MIN_POS_VALUE));
          println!("{}", std::f32::to_string(std::f32::MAX_VALUE));
          println!("{}", std::f32::to_string(std::f32::consts::PI));
      }
      

      输出:

      0.00000000000000000000000000000000000000000000140129852294921875
      0.000000000000000000000000000000000000000000022420775890350341796875
      0.000000000000000000000000000000000000011754944324493408203125
      340282368002860660002286082464244022240
      3.1415927410125732421875
      

      【讨论】:

      • hmm,“非常大”似乎有点奇怪,打印出我实际拥有的准确度会很好,如果我理解你的答案会更像{:.31f} 我想知道那个神奇的数字可以从我正在阅读f32 的事实中得出结论?
      • 我找到了更好的东西;看我的编辑。 (编辑:当我进行此编辑时,我还没有看到 Arjan 的答案。)
      • 如果我在f32 中打印1 的确切值,使用这种方法我怎么知道我有32 位精度?
      • 您无法将十进制数的精度与二进制数的精度联系起来。也许您想以二进制或十六进制打印浮点数?见to_str_hexto_str_radix_special
      【解决方案4】:

      此答案是为 Rust 0.12.0 编写的,不适用于 Rust 1.x。


      您可以使用std::f32::to_string 打印所有数字。

      use std::f32;
      
      fn main() {
          let pi: f32 = 3.1415926536897932384626;
          let k1: f32 = 0.6072529350088812561694; // 1/k
      
          println!("pi is {}", f32::to_string(pi));
          println!("k1 is {}", f32::to_string(k1));
      }
      

      输出:

      pi is 3.1415927410125732421875
      k1 is 0.607252979278564453125
      

      【讨论】:

      • 您能否看看我对 Francis Gagné 的评论,看看您的解决方案是否只显示我们实际知道的数字?
      【解决方案5】:

      要修剪尾随的零和点,您可以:

      println!(
        "number = {}",
        format!("{:.2}", x).trim_end_matches(['.', '0'])
      );
      

      例子:

      input output
      3.359 3.36
      3.3 3.3
      3.0 3

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-25
        • 1970-01-01
        • 2020-08-04
        • 2012-10-25
        • 2016-09-02
        • 2012-06-09
        • 2015-05-17
        相关资源
        最近更新 更多