最大的 uint64,可以在 C/C++ 的浮点数中准确表示 [重复]

Largest uint64 which can be accurately represented in a float in C/C++ [duplicate]

提问人:Paul Grinberg 提问时间:9/29/2022 最后编辑:273KPaul Grinberg 更新时间:9/30/2022 访问量:257

问:

我知道浮点精度只有这么多位。毫不奇怪,以下代码认为 和 是相等的。我正在尝试编写一个函数来检测这种类型的“转换溢出”,因为缺乏适当的术语。我以为我可以以某种方式使用,但这是不正确的。正确的方法是什么?(float)(UINT64_MAX)(float)(UINT64_MAX - 1)FLT_MAX

#include <iostream>
#include <cstdint>

int main()
{
  uint64_t x1(UINT64_MAX);
  uint64_t x2(UINT64_MAX - 1);
  float f1(static_cast<float>(x1));
  float f2(static_cast<float>(x2));
  std::cout << f1 << " == " << f2 << " = " << (f1 == f2) << std::endl;
  return 0;
}
C++ 浮点 类型转换 精度

评论

1赞 NathanOliver 9/29/2022
没有一种方法可以做到这一点。32 位浮点数有 23 位尾数,因此您可以安全地存储 23 位数字。对于较大的数字,这取决于它们的表示方式。例如,2^60 应该没有问题,因为这不需要任何尾数位(我认为)。
1赞 NathanOliver 9/29/2022
你试图通过这样做来解决什么实际问题?我们也许可以提供不同的解决方案。
3赞 Eric Postpischil 9/29/2022
@NathanOliver:IEEE-754 binary32 又名“单精度”的常用格式具有 24 位有效,而不是 23。23 个编码在主有效字段中,一个编码在指数字段中,格式可以表示所有 24 位整数,而不仅仅是 23。(“Significand”是首选术语;“尾数”是一个古老的词,表示对数的小数部分。有效数是对数的,尾数是对数的。float
3赞 Eric Postpischil 9/29/2022
不要同时标记 C 和 C++,除非询问两种语言之间的差异或交互。选择一种语言并删除另一种标记。在不同的语言中,解决此问题的技术是不同的(尽管一种可能适用于另一种)。我想我在某处对 C++ 有一个相关的答案。
1赞 Eljay 9/29/2022
你的意思是可以容纳的最大整数值,可以随着保真度的增加而增加吗?(在某个时候,它要么停止递增,要么递增。float12

答:

2赞 chux - Reinstate Monica 9/29/2022 #1

最大的 uint64,可以在浮点数
中准确表示 正确的方法是什么?

当 时,我们正在寻找以下形式的 a,其中 是值中可编码的最大位数。这通常是 24。请参见 。FLT_RADIX == 2uint64_tnfloatFLT_MANT_DIG<float.h>

111...(total of n binary digits)...111000...(64-n bits all zero)...000.
//
//1234561234567890
0xFFFFFF0000000000, in decimal: 18446742974197923840
// e.g. 
~( (1ull << (64-FLT_MANT_DIG)) - 1)

评论

0赞 Davis Herring 9/29/2022
请注意,下一个较小的 binary32 值是 0xFFFFFE0000000000,因此很可能需要0x1000000来进行范围检查。
0赞 chux - Reinstate Monica 9/29/2022
@DavisHerring没错,就可以在OP的问题中解读出各种目标。我专注于标题。
1赞 AProgrammer 9/29/2022 #2

以下函数为您提供了可在浮点类型中精确表示的最高整数,以便所有较小的正整数也可精确表示。

template<typename T>
T max_representable_integer()
{
    return std::scalbn(T(1.0), std::numeric_limits<T>::digits);
}

它在浮点中进行计算,因为对于某些人来说,结果可能无法在 .uint64_t

评论

1赞 Eric Postpischil 9/29/2022
避免在需要精确性的情况下用于幂。虽然浮点格式允许在这种情况下产生确切的结果,但糟糕的实现可能会产生不准确的结果。 是更好的选择。powpowpowscalbn
0赞 Eric Postpischil 9/29/2022
该问题不要求“在浮点类型中可精确表示的最高整数,以便所有较小的正整数也可精确表示”。