C语言 长双精度值的相同uintmax_t表示

gev0vcfq  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(107)

为什么一些长双精度值具有相同的uintmax_t表示。在哈希表中使用这些值作为键时会出现问题。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

union U{
    uintmax_t u;
    long double d;
};
int main(void)
{
    union U u1, u2;
    u1.d = 1.0L;
    u2.d = 2.0L;
    printf("u1.u: %"PRIuMAX"\n", u1.u);
    printf("u2.u: %"PRIuMAX"\n", u2.u);
    
    //output:
    u1.u: 9223372036854775808
    u2.u: 9223372036854775808
}

字符串

eh57zj3b

eh57zj3b1#

对于其他不兼容类型的对象(如long double),没有“uintmax_t表示”。您所观察到的是,您的C实现的long double1.0L表示的前sizeof(uintmax_t)字节与2.0L表示的字节数相同。由于long double值是不同的,因此它们之间的差异必须出现在第一个sizeof(uintmax_t)字节之外。
这并不奇怪,因为uintmax_t不需要和long double一样宽,而且这些特定值之间的差将位于指数字段的最低有效位。这可能是最后一个非填充位。long double可具有80个或更多个非填充位,而uintmax_t通常仅为64位宽。
特别是,您看到的输出是263的十进制表示,这正是我在示例中所期望的

  • 64位uintmax_t,以及
  • IEEE风格的浮点表示法,它
  • 以64位尾数字段开始,或
  • 以较宽的尾数字段开始并且以小端顺序排列,
  • 假设尾数的字节顺序与uintmax_t的字节顺序相同。

这些都是非常合理的条件,产生long double s的指数场对观察到的输出没有贡献的效果。
更一般地说,由于您的long doubleuintmax_t宽,正如您在注解中所表达的那样,我们有充分的理由期待会有 * 许多 * 对不同的long double与第一个sizeof(uintmax_t)字节匹配。uintmax_t没有足够的不同值来为每个不同的long double值分配一个不同的值(除非您的long double反常地将其所有额外的8个字节专门用作填充,但它显然没有)。

yqkkidmi

yqkkidmi2#

在哈希表中使用这些值作为键时会出现问题。
由于OP的long double字节大小超过了uintmax_t字节大小(因此在uintmax_t中并不是所有long double中的差异都能看到),而且显然代码被设计为使用uintmax_t预散列值,因此考虑合并额外的数据。
一些说明性代码:

#include <complex.h>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>

// Form a union of the various types for the hash table.
typedef union {
  long double ld;
  // Maybe other potential data types?
  int (*f)(); // Function pointer
  void *v;    // Object pointer
  complex double cd;
  int i;
// ...
} data;

// Form a union of the data with an array of uintmax_t.
#define HASH_N ((sizeof(data) + sizeof(uintmax_t) - 1)/sizeof(uintmax_t))
typedef union {
  data d;
  uintmax_t u[HASH_N];
} hash;

uintmax_t prehash_long_double(long double ld) {
  hash h = {.d.ld = ld};
  for (size_t i = 1; i < HASH_N; i++) {
    h.u[0] ^= h.u[i];  // Merge data
  }
  return h.u[0];
}

字符串

相关问题