我正在为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);
}
}
使用精度格式说明符;.
,后跟您希望看到的小数点精度:
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,这比这两个f32
s中的小数点数量都多。
pi is 3.14159274101257324218750000000000
k1 is 0.60725295543670654296875000000000
请注意,这些值不再匹配;浮点值很难!如注释中所述,您可能希望打印为十六进制,甚至使用十六进制的文字。
使用精度格式说明符是正确的答案,但要打印所有可用的精度,只需避免指定要显示的位数:
// prints 1
println!("{:.}", 1_f64);
// prints 0.000000000000000000000000123
println!("{:.}", 0.000000000000000000000000123_f64);
这样,您就不必截断值,也不必修剪多余的零,而且无论值是很大还是很小,所有值的显示都是正确的。
游乐场示例
为了完整性,精度格式说明符还支持指定固定精度(根据接受的答案):
// 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
这个答案是为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
这个答案是为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
要修剪尾部的零和点,可以执行以下操作:
println!(
"number = {}",
format!("{:.2}", x).trim_end_matches(['.', '0'])
);
示例:
输入 | 输出 |
---|---|
3.359 | 3.36 |
3.3 | 3.3 |
3.0 | 3 |
IMHO如果您想存储高精度的浮点数,就无法绕过双十进制机箱,因为您需要像OP:
这样的所有数字0.6072529350088812
561694
use bigdecimal::BigDecimal;
fn main() {
let pi = BigDecimal::parse_bytes(b"3.1415926536897932384626", 10);
let k1 = BigDecimal::parse_bytes(b"0.6072529350088812561694", 10); // 1/k
println!("pi is {pi:?}");
println!("k1 is {k1:?}");
}
获取:pi is Some(BigDecimal("3.1415926536897932384626"))
k1 is Some(BigDecimal("0.6072529350088812561694"))