簡體   English   中英

Rust:f32 上奇怪的基於狀態的舍入行為

[英]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 {

編譯器現在可以確定uv的值屬於f32類型。

然后你使用.dot()方法,它可以處理f32f64 uv的類型已經定義為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM