如何确定给定的INT64_T是否可以无损地存储在双倍中
How to determine if a given int64_t can be stored losslessly in a double?
我想确定是否可以将给定的64位整数存储在双重中。现在我有此代码:
static_cast<int64_t>(static_cast<double>(value)) == value
但是,由于某些平台上的精度过高,我认为这并不总是准确的。
请注意,我不是要提供最大的整数,以便所有较小的整数都可以无损地存储,即2^53。我需要知道,即使n 1和n-1不是。
标准库中是否有某些内容,也许与std::numeric_limits
相似,这会告诉我?
只要低位为0,就可以设置更多的高阶位(因为您可以增加双重指数)。我减少了未签名的要求,以使点移动不必担心标志位,但我相信它应该是适应性的。
bool fits_in_double_losslessly (uint64_t v)
{
const uint64_t largest_int = 1ULL << 53;
while ((v > largest_int) && !(v & 1))
{
v >>= 1;
}
return v <= largest_int;
}
从最低位设置中减去最高位,添加一个以避免围栏误差,与Mantissa中的位数相比。请记住,Mantissa的主要1是IEEE的隐含。如果Mantissa可以容纳整个使用的位,则可以准确存储该数字。
或者,查看static_cast<double>(m) != static_cast<double>(m+1) && static_cast<double>(m) != static_cast<double>(m-1)
是否。这适用于 indigned 值,但是对于A 签名类型,便携式代码将需要检查该值是否不会溢出或底流,因为这是未定义的行为。再说一次,某些实现也可能没有int64_t
。但是,在许多实现方面,签名的溢出或下水流仍然会给您一个不同的数字,其符号将正确测试。
其他答案中的一个共同主题是您是否可以假设双打是通过IEEE 754实现的。
我会争辩说,对于许多目的,您的原始方法最好:将给定的INT64_T施放为双重,然后将结果分配回第二个INT64_T,然后比较两个。
关于您对过度精确度的担忧,只要您知道该值实际上已写入记忆和回复,这不应该适用,因为在那个阶段,编译器不应有任何方法可以存储该变量的"过度精度"。根据您原始链接的答案,我相信以下示例足以迫使这种行为:
bool losslessRoundTrip(int64_t valueToTest)
{
double newRepresentation;
*((volatile double *)&newRepresentation) = static_cast<double>(valueToTest);
int64_t roundTripValue = static_cast<int64_t>(newRepresentation);
return roundTripValue == valueToTest;
}
我怀疑仅将new陈述宣布为挥发性就足够了,但是我不够使用挥发性的关键字来确定,所以我只是简单地从链接中调整了解决方案。
关于您的原始方法的好处是,只要您只关心是否可以回到这样的初始类型,它应该为支持正确的演员和操作员提供几乎所有支持的所有支持。例如,这是一个通用实现:
template<typename T1, typename T2>
bool losslessRoundTrip(T1 valueToTest)
{
T2 newRepresentation;
*((volatile T2 *)&newRepresentation) = static_cast<T2>(valueToTest);
T1 roundTripValue = static_cast<T1>(newRepresentation);
return roundTripValue == valueToTest;
}
请注意,这可能不是您问题的最佳答案,因为检查您是否可以通过...将其存储为双人物似乎仍然是一个作弊。不过,我不知道该如何避免依靠内部表示的力学。
它也不是检查它是否无损地存储在双重中,而是从INT64_T到双重的往返,然后返回INT64_T在该平台上是无损的。我不知道是否有可能出现在两个方向上应用铸造时取消的铸造错误(我会吸引更多知识的人),但是我认为,我通常认为它足够接近如果我可以转换回同一类型,则"无损"如果我可以将初始值恢复。
您需要测试较低的位。如果它们为零,则该数字将无损存储。
- 将字符串存储在c++中的稳定内存中
- 如何确定我已使用非编码文件到达 EOF?
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在C++中确定文本文件中的元素是字符还是数字
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 存储模板类型以强制转换回派生<T>
- Python中的for循环与C++有何不同
- 如何确定 SQLite 文件在 QML LocalStorage 中的存储位置
- 如何确定给定的INT64_T是否可以无损地存储在双倍中
- 值未存储在向量中 - 不确定这里发生了什么
- 对"检查更新"按钮进行编程以确定存储库中的更改
- 什么是C++中的不确定行为?它与未定义的行为有何不同
- 编译时方法,用于确定对象是否具有自动存储持续时间
- 什么是'应仅访问先前值以确定要存储的值'意思是
- 如何在编译时确定git存储库的状态
- 如何为分层结构确定某些东西存储在内存中的位置