How do I print a Rust floating-point number with all available precision?

后端 未结 4 1973
长情又很酷
长情又很酷 2021-01-17 17:47

I am implementing the CORDIC algorithm for the sin trigonometric function. In order to do this, I need to hardcode/calculate a bunch of arctangent values. Right

相关标签:
4条回答
  • 2021-01-17 18:02

    This answer was written for Rust 0.12.0 and doesn't apply to Rust 1.x.


    You can use std::f32::to_string to print all the digits.

    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));
    }
    

    Output:

    pi is 3.1415927410125732421875
    k1 is 0.607252979278564453125
    
    0 讨论(0)
  • 2021-01-17 18:11

    Use the precision format specifier; a . followed by the number of decimal points of precision you'd like to see:

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

    I chose 32, which is more than the number of decimal points in either of these f32s.

    pi is 3.14159274101257324218750000000000
    k1 is 0.60725295543670654296875000000000
    

    Note that the values no longer match up; floating point values are difficult! As mentioned in a comment, you may wish to print as hexadecimal or even use your literals as hexadecimal.

    0 讨论(0)
  • 2021-01-17 18:18

    Using the precision format specifier is the correct answer, but to print all available precision, simply refrain from specifying the number of digits to display:

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

    This way, you will not truncate values nor will you have to trim excess zeros, and the display will be correct for all values, regardless of whether they are very large or very small.

    Playground example

    For completeness, the precision format specifier also supports a specifying a fixed precision (as per the accepted answer):

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

    as well as a precision specified at runtime (does not need to be const, of course):

    // prints 1.00
    const PRECISION: usize = 2;
    println!("{:.*}", PRECISION, 1_f64); // precision specifier immediately precedes positional argument
    
    0 讨论(0)
  • 2021-01-17 18:27

    This answer was written for Rust 0.12.0 and doesn't apply to Rust 1.x.


    You can use the to_string function in std::f32 (not to be confused with the to_string method):

    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));
    }
    

    Output:

    0.00000000000000000000000000000000000000000000140129852294921875
    0.000000000000000000000000000000000000000000022420775890350341796875
    0.000000000000000000000000000000000000011754944324493408203125
    340282368002860660002286082464244022240
    3.1415927410125732421875
    
    0 讨论(0)
提交回复
热议问题