【发布时间】:2016-02-03 03:15:02
【问题描述】:
我正在使用 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,但是异常会分配到内存中。即使我取消分配它。过多的分配/解除分配仍然会耗尽系统资源。
因此,有没有办法在不引发任何异常的情况下检测双精度值的有效性?
【问题讨论】:
-
在标准 C++ 中没有办法。也许您可以检查 IEEE754 规范并编写一些代码,这可能会起作用。
-
如果您的编译器支持 C++11,您应该使用来自
<cmath>的std::isfinite。请参阅cppreference.com 了解更多信息。 -
@paddy 仍然无法解决问题
-
这只是反对使用二进制数据格式的论据。确定基于轻量级可解析文本的文件格式(如 xml 或 yaml)的有效性要容易得多。
-
_finite()只是检查 valid 有限值。你的问题比这更难:一个不是 fpu 有效数字的位模式,它(我相信)正在调用一个陷阱处理程序。你可以捕捉到这样的 fpu 陷阱。见msdn.microsoft.com/en-us/library/te2k2f2t.aspx。此外,msdn.microsoft.com/en-us/library/c9676k6h.aspx 用于设置 fpu 模式,包括处理程序调用。