提问人:Paul Grinberg 提问时间:9/29/2022 最后编辑:273KPaul Grinberg 更新时间:9/30/2022 访问量:257
最大的 uint64,可以在 C/C++ 的浮点数中准确表示 [重复]
Largest uint64 which can be accurately represented in a float in C/C++ [duplicate]
问:
我知道浮点精度只有这么多位。毫不奇怪,以下代码认为 和 是相等的。我正在尝试编写一个函数来检测这种类型的“转换溢出”,因为缺乏适当的术语。我以为我可以以某种方式使用,但这是不正确的。正确的方法是什么?(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;
}
答:
2赞
chux - Reinstate Monica
9/29/2022
#1
最大的 uint64,可以在浮点数
中准确表示 正确的方法是什么?
当 时,我们正在寻找以下形式的 a,其中 是值中可编码的最大位数。这通常是 24。请参见 。FLT_RADIX == 2
uint64_t
n
float
FLT_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
避免在需要精确性的情况下用于幂。虽然浮点格式允许在这种情况下产生确切的结果,但糟糕的实现可能会产生不准确的结果。 是更好的选择。pow
pow
pow
scalbn
0赞
Eric Postpischil
9/29/2022
该问题不要求“在浮点类型中可精确表示的最高整数,以便所有较小的正整数也可精确表示”。
评论
float
float
1
2