【问题标题】:Why does transmuting a f64 into u64 and then back into f64 result in a different value?为什么将 f64 转换为 u64 然后再转换回 f64 会导致不同的值?
【发布时间】:2020-09-01 21:47:16
【问题描述】:

我有一个独特的场景,我想使用f64 作为HashMap 中的键。特别是我知道f64 永远不会是NaN,我可以容忍f64s 应该是相等的,但不是。所以我transmute()f64u64。但是,当我将u64HashMaptransmute() 拉回f64 时,它是一个不同的值。下面和playground上的代码。

use std::collections::HashMap;

fn main() {
    let x = 5.0;
    let y: u64 = unsafe { std::mem::transmute(x) };
    let x: f64 = unsafe { std::mem::transmute(y) };
    println!("y: {}, x: {}", y, x);
    let mut hash = HashMap::new();
    hash.insert(y, 8);
    for (y, _) in &hash {
        let x: f64 = unsafe { std::mem::transmute(y) };
        println!("y: {}, x: {}", y, x);
    }
}

我错过了什么?

【问题讨论】:

    标签: hash rust key unsafe


    【解决方案1】:

    当您编写for (y, _) in &hash 时,y 将成为键的引用,然后您将其转换为无意义的浮点数。

    如果你写for (&y, _) in &hash或使用*y,你会得到预期的值。

    转换错误的东西是为什么在使用transmute 时永远不应该推断类型,并且应该始终避免使用transmute。特别是,对于这种特定的转换,有安全方法f64::to_bitsf64::from_bits。一种更惯用的方法是使用HashMap<FloatWrapper, Value>,其中FloatWrapper 实现Ord

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 2022-07-02
      • 2013-11-15
      相关资源
      最近更新 更多