为什么一些长双精度值具有相同的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
}
字符串
2条答案
按热度按时间eh57zj3b1#
对于其他不兼容类型的对象(如
long double
),没有“uintmax_t
表示”。您所观察到的是,您的C实现的long double
值1.0L
表示的前sizeof(uintmax_t)
字节与2.0L
表示的字节数相同。由于long double
值是不同的,因此它们之间的差异必须出现在第一个sizeof(uintmax_t)
字节之外。这并不奇怪,因为
uintmax_t
不需要和long double
一样宽,而且这些特定值之间的差将位于指数字段的最低有效位。这可能是最后一个非填充位。long double
可具有80个或更多个非填充位,而uintmax_t
通常仅为64位宽。特别是,您看到的输出是263的十进制表示,这正是我在示例中所期望的
uintmax_t
,以及uintmax_t
的字节顺序相同。这些都是非常合理的条件,产生
long double
s的指数场对观察到的输出没有贡献的效果。更一般地说,由于您的
long double
比uintmax_t
宽,正如您在注解中所表达的那样,我们有充分的理由期待会有 * 许多 * 对不同的long double
与第一个sizeof(uintmax_t)
字节匹配。uintmax_t
没有足够的不同值来为每个不同的long double
值分配一个不同的值(除非您的long double
反常地将其所有额外的8个字节专门用作填充,但它显然没有)。yqkkidmi2#
在哈希表中使用这些值作为键时会出现问题。
由于OP的
long double
字节大小超过了uintmax_t
字节大小(因此在uintmax_t
中并不是所有long double
中的差异都能看到),而且显然代码被设计为使用uintmax_t
预散列值,因此考虑合并额外的数据。一些说明性代码:
字符串