You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何不同long double值的uintmax_t表示相同?哈希表键冲突问题

为什么部分long double值会有相同的uintmax_t表示?

核心原因

  • 存储结构与类型长度不匹配:在x86架构下,long double一般是80位扩展精度格式(占10字节),包含1位符号位、15位指数位和64位尾数位(显式存储整数位)。而uintmax_t在多数系统中是64位(8字节),通过union访问时只会读取long double的低64位——也就是尾数位部分。
  • 特定值的尾数位完全一致:1.0L和2.0L的差异仅体现在指数位上:1.0L的指数是偏移后的0(16383),2.0L的指数是偏移后的1(16384),但两者的尾数位都是0x8000000000000000(对应整数位1,其余位全0)。因为union只取了尾数位的64位,所以它们的uintmax_t表示完全相同。

解决哈希冲突的方法

不要直接通过union把long double转成uintmax_t当哈希键,建议用覆盖所有字节的哈希方式:

  • 将long double转为字节数组,对所有字节计算哈希,示例代码:
    #include <stdint.h>
    #include <string.h>
    
    uint64_t hash_long_double(long double d) {
        unsigned char bytes[sizeof(long double)];
        memcpy(bytes, &d, sizeof(long double));
        uint64_t hash = 0;
        for (size_t i = 0; i < sizeof(long double); i++) {
            hash = hash * 31 + bytes[i]; // 简单多项式哈希实现
        }
        return hash;
    }
    
  • 也可以根据long double的存储结构,拆分出符号位、指数位和尾数位,组合后生成哈希值,确保所有位都参与计算。

内容的提问来源于stack exchange,提问作者kaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:10:04