gpt4 book ai didi

Rust:f32 上奇怪的基于状态的舍入行为

转载 作者:行者123 更新时间:2023-12-05 03:22:13 27 4
gpt4 key购买 nike

当使用特定值计算两个 nalgebra::Vector3 结构的点积时,我得到以下行为 ( link to playground ):

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

我必须能够依靠计算始终保持不变。有什么想法吗?

与我之前的问题相关,由于示例无效,我关闭了该问题 previous question

最佳答案

正如@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。如果没有额外信息,编译器将作为 default float type in Rust 落入 f64。 .

当您调用 dot(u, v) - 您让编译器知道确切的类型,因为您在函数声明中指定了它们:

 3| fn dot(v1: Vector3<f32>, v2: Vector3<f32>) -> f32 {

编译器现在确定 uv 的值属于 f32 类型。

那么您正在使用 .dot() 方法,它可以处理 f32f64uv的类型已经定义为f32,变量的类型不能改变,但是会导致.dot( ) 可以处理 f32,这让编译器很高兴。此时你得到:

Run 1:
-1413.93554687500000000000000000000000
-1413.93554687500000000000000000000000

之后,您将定义具有相同名称的新变量 - 同样,编译器没有关于变量类型的明确信息。但是这次没有 dot(u, v) 调用,只有 .dot() 而后者不需要 f32,所以编译器使用默认的 f64。最后你得到:

Run2:
-1413.93548250214189465623348951339722

关于Rust:f32 上奇怪的基于状态的舍入行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72774605/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com