hash - 为什么将 f64 转换为 u64 然后再转换回 f64 会导致不同的值?

标签 hash rust key unsafe

我有一个独特的场景,我想使用 f64 作为 HashMap 中的键。特别是我知道 f64 永远不会是 NaN 并且我可以容忍应该相等但不相等的 f64s。所以我将transmute() f64 转为u64。但是,当我将 u64HashMaptransmute() 拉回 f64 时,它是一个不同的值(value)。代码下方和 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);
    }
}

我错过了什么?

最佳答案

当你写 for (y, _) in &hash , y将是键的引用,然后您将其转换为无意义的 float 。

你应该写for (&y, _) in &hash或使用 *y , 你会得到期望值。

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

关于hash - 为什么将 f64 转换为 u64 然后再转换回 f64 会导致不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63695874/

相关文章:

php - 将确认密码与散列密码进行比较 |拉维尔 4

rust - 使用函数指针时为 "Expected fn item, found a different fn item"

字符串到 str slice,str slice 的生命周期不够长

events - SDL 中的输入(按下按键时)

sorting - Lisp 排序功能键

passwords - 密码散列 : PBKDF2 (using sha512 x 1000) vs Bcrypt

javascript - 输入哈希值来重置密码而不是实际用户密码

.net - 为什么在同一个数据库中保存散列密码的盐是安全的?

rust - 简洁地初始化字符串向量

java - 检查 JSON 字符串中是否存在多个键 - Java