gpt4 book ai didi

c++ - 防止 "Float-point invalid operation"异常?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:05 24 4
gpt4 key购买 nike

我正在使用 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,但异常会在内存中分配。即使我取消分配它。太多的分配/释放仍然会耗尽系统资源。

因此,有没有办法在不引发任何异常的情况下检测 double 值的有效性?

最佳答案

我本以为std::isnan会做你需要做的并且最有效地做。如果您在平台上的实现不是这种情况,但假设 float 使用 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++ - 防止 "Float-point invalid operation"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35167866/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com