如何在C中使用nan和inf?
我有一个数值方法,如果出现错误,可以返回 nan 或 inf,出于测试目的,我想暂时强制它返回 nan 或 inf 以确保正确处理情况。是否有可靠的、独立于编译器的方法在 C 中创建 nan 和 inf 的值?
经过大约 10 分钟的谷歌搜索后,我只能找到依赖于编译器的解决方案。
I have a numerical method that could return nan or inf if there was an error, and for testing purposed I'd like to temporarily force it to return nan or inf to ensure the situation is being handled correctly. Is there a reliable, compiler-independent way to create values of nan and inf in C?
After googling for about 10 minutes I've only been able to find compiler dependent solutions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
您可以测试您的实现是否具有它:
C99(或至少是最新草案)保证了INFINITY的存在,并且“扩展为表示正数或无符号的float类型的常量表达式”
无穷大(如果可用);否则为在转换时溢出的 float 类型的正常量。”
NAN
可以定义也可以不定义,并且“当且仅当实现支持 float 类型的安静 NaN 时才定义。它扩展为代表安静 NaN 的 float 类型常量表达式。”请注意,如果您正在比较浮点值,并且 do:
即使这样,
也是 false。检查 NaN 的一种方法是:
您还可以执行以下操作: < code>a != a 来测试
a
是否为 NaN。还有
isfinite()
、isinf()
、< C99 中math.h
中的 code>isnormal() 和signbit()
宏也有
nan
函数:(参考:n1256)
。
文档 NAN
You can test if your implementation has it:
The existence of
INFINITY
is guaranteed by C99 (or the latest draft at least), and "expands to a constant expression of type float representing positive or unsignedinfinity, if available; else to a positive constant of type float that overflows at translation time."
NAN
may or may not be defined, and "is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN."Note that if you're comparing floating point values, and do:
even then,
is false. One way to check for NaN would be:
You can also do:
a != a
to test ifa
is NaN.There is also
isfinite()
,isinf()
,isnormal()
, andsignbit()
macros inmath.h
in C99.C99 also has
nan
functions:(Reference: n1256).
Docs INFINITY
Docs NAN
没有独立于编译器的方法可以做到这一点,因为 C(或 C++)标准都没有规定浮点数学类型必须支持 NAN 或 INF。
编辑:我刚刚检查了 C++ 标准的措辞,它说这些函数(模板类 numeric_limits 的成员):
将返回 NAN 表示“如果可用”。它没有扩展“如果可用”的含义,但大概是“如果实现的 FP 代表支持它们”之类的内容。类似地,有一个函数:
它返回一个正的 INF 表示“如果可用”。
这些都是在
标头中定义的 - 我猜测 C 标准有类似的东西(可能也是“如果可用”),但我没有当前 C99 标准的副本。There is no compiler independent way of doing this, as neither the C (nor the C++) standards say that the floating point math types must support NAN or INF.
Edit: I just checked the wording of the C++ standard, and it says that these functions (members of the templated class numeric_limits):
wiill return NAN representations "if available". It doesn't expand on what "if available" means, but presumably something like "if the implementation's FP rep supports them". Similarly, there is a function:
which returns a positive INF rep "if available".
These are both defined in the
<limits>
header - I would guess that the C standard has something similar (probably also "if available") but I don't have a copy of the current C99 standard.这适用于
float
和double
:编辑:
正如有人已经说过的,旧的 IEEE 标准说
这样的价值观应该引发陷阱。但是新的编译器
几乎总是关闭陷阱并返回
给定值,因为捕获会干扰错误
处理。
This works for both
float
anddouble
:Edit:
As someone already said, the old IEEE standard said that
such values should raise traps. But the new compilers
almost always switch the traps off and return the
given values because trapping interferes with error
handling.
一种独立于编译器的方式,但不是独立于处理器的方式来获取这些:
这应该适用于任何使用 IEEE 754 浮点格式的处理器(x86 可以)。
更新:已测试并更新。
A compiler independent way, but not processor independent way to get these:
This should work on any processor which uses the IEEE 754 floating point format (which x86 does).
UPDATE: Tested and updated.
和
and
我通常使用
or
,它至少在 IEEE 754 上下文中有效,因为可表示的最高双精度值大约为
1e308
。1e309
的效果与1e99999
一样好,但三个 9 就足够了并且容易记住。由于这要么是双精度字面量(在#define
情况下),要么是实际的Inf
值,因此即使您使用 128 位(“long双”)浮动。I usually use
or
which works at least in IEEE 754 contexts because the highest representable double value is roughly
1e308
.1e309
would work just as well, as would1e99999
, but three nines is sufficient and memorable. Since this is either a double literal (in the#define
case) or an actualInf
value, it will remain infinite even if you're using 128-bit (“long double”) floats.这是定义这些常量的简单方法,我很确定它是可移植的:
当我运行此代码时:
我得到:
Here is a simple way to define those constants, and I'm pretty sure it's portable:
When I run this code:
I get:
在 MSVC 中,在
Correct_math.h
中定义了以下内容,该内容包含在math.h
中:In MSVC, the following is defined in
correct_math.h
, which is included inmath.h
:我也很惊讶这些不是编译时间常数。但我想您可以通过简单地执行返回此类无效结果的指令来轻松创建这些值。除以 0、0 的对数、90 的 tan,诸如此类。
I'm also surprised these aren't compile time constants. But I suppose you could create these values easily enough by simply executing an instruction that returns such an invalid result. Dividing by 0, log of 0, tan of 90, that kinda thing.