[英]Rust: Strange state-based rounding behaviour on f32
当使用特定值计算两个nalgebra::Vector3
结构的点积时,我得到以下行为( 链接到操场):
use nalgebra::{Point3, Vector3}; // 0.31.0
fn dot(v1: Vector3<f32>, v2: Vector3<f32>) -> f32 {
v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
}
fn main() {
println!("Run 1:");
let u = Vector3::new(1000., -1000., 0.);
let v = Vector3::new(-0.69294637441651, 0.720989108085632, 0.);
println!(
"self-written dot-product: \t{:.32}",
dot(u, v)
);
println!(
"nalgebra dot-product: \t\t{:.32}",
u.dot(&v)
);
println!("\nRun2:");
let u = Vector3::new(1000., -1000., 0.);
let v = Vector3::new(-0.69294637441651, 0.720989108085632, 0.);
println!(
"nalgebra dot-product: \t\t{:.32}",
u.dot(&v)
);
}
输出:
Run 1:
self-written dot-product: -1413.93554687500000000000000000000000
nalgebra dot-product: -1413.93554687500000000000000000000000
Run2:
nalgebra dot-product: -1413.93548250214189465623348951339722
我必须能够依靠计算始终保持不变。 有什么想法吗?
与我之前的问题相关,由于非工作示例,我关闭了之前的问题
正如@aedm 在评论中提到的那样,您的dot()
函数是导致这种行为的原因。 作为一个初学者,我不太清楚这到底是什么原因,所以我在这里解释一下。
第一次定义变量时,
9| println!("Run 1:");
10| let u = Vector3::new(1000., -1000., 0.);
11| let v = Vector3::new(-0.69294637441651, 0.720989108085632, 0.);
Rust 编译器不知道值的确切类型,它只知道它是float
。 如果没有额外的信息,编译器会选择f64
作为Rust 中的默认浮点类型。
当您调用dot(u, v)
- 您让编译器知道确切的类型,因为您在函数声明中指定了它们:
3| fn dot(v1: Vector3<f32>, v2: Vector3<f32>) -> f32 {
编译器现在可以确定u
和v
的值属于f32
类型。
然后你使用.dot()
方法,它可以处理f32
和f64
。 u
和v
的类型已经定义为f32
,变量的类型不能改变,但是由于.dot()
可以处理f32
,这让编译器很高兴。 此时你得到:
Run 1:
-1413.93554687500000000000000000000000
-1413.93554687500000000000000000000000
之后,您将定义具有相同名称的新变量 - 编译器再次没有关于变量类型的明确信息。 但是这次没有dot(u, v)
调用,只有.dot()
并且后者不需要f32
,所以编译器使用默认的f64
。 最后你得到:
Run2:
-1413.93548250214189465623348951339722
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.