防止"Float-point invalid operation"异常?
Prevent "Float-point invalid operation" exception?
我正在使用Visual C++将二进制数据加载到float
中,如下所示:
double dValue;
memcpy(&dValue, lpData, sizeof(dValue));
对于正常情况,这将正常工作。但是,对于极少数情况,当二进制数据损坏时,dValue
将无效,对其的任何进一步操作都将导致"浮点无效操作"异常。
我在调试器中检查dValue
,它显示为-1.#QNAN00000000000
。
为了防止异常,我需要在从二进制数据加载dValue
后对其进行验证。我尝试使用:
if (_finite(dValue))
{
… do some tasks…
}
但无效dValue
仍然会导致_finite
函数引发Float-point invalid operation
异常。尽管_finite(dValue)
将正确返回 0,但异常将在内存中分配。即使我解除分配它。过多的分配/取消分配仍将耗尽系统资源。
因此,有没有办法在不引发任何异常的情况下检测双精度值的有效性?
我本以为std::isnan
会做你需要的,并且做得最有效。如果您的平台上的实现不是这种情况,但假设浮点数使用 IEEE 754 格式,您觉得很舒服,那么自己编写这些函数并不难。
inline constexpr bool
isnan(const std::uint32_t bits) noexcept
{
constexpr std::uint32_t exponent = UINT32_C(0x7f800000);
constexpr std::uint32_t mantissa = UINT32_C(0x007fffff);
return ((bits & exponent) == exponent) && ((bits & mantissa) != 0);
}
inline constexpr bool
isnan(const std::uint64_t bits) noexcept
{
constexpr std::uint64_t exponent = UINT64_C(0x7ff0000000000000);
constexpr std::uint64_t mantissa = UINT64_C(0x000fffffffffffff);
return ((bits & exponent) == exponent) && ((bits & mantissa) != 0);
}
实现isfinite
更简单,您只需要检查该(bits & exponent) != exponent
。要实现isnormal
,请检查((bits & exponent) != exponent) && ((bits & exponent) != 0))
。请注意,根据此定义,零不是"正常"。
请注意,这些函数对整型类型进行操作。这是故意的。您的代码会将字节fread
成一个整数,您将整数传递给函数以确定它是否表示"不是数字",并且(仅)如果它不表示,则将字节memcpy
为浮点类型。
相关文章:
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 尝试使用智能指针时引发异常
- 函数如何通知用户它基于函数原型抛出异常?
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- 防止"Float-point invalid operation"异常?