ruh*_*ner 9 c++ nan division infinity
我有一个可能是零的数字.我除以那个数字,所以我想测试它是否为零以防止NaN和无穷大.由于分区内的舍入错误,我是否仍然可以创建NaNs /无穷大?
double x; // might be zero
double y;
if(x != 0) return y / x;
Run Code Online (Sandbox Code Playgroud)
编辑
谢谢你的回复.我会添加一些子问题.
1)假设x和y都不是NaN/+ INF或-INF,会导致-INF/+ INF导致更多的CPU周期或任何其他不希望的行为的分割?(会崩溃吗?)
2)有没有办法防止分裂导致无穷大?使用偏移等.
可以通过非零划分仍然创建纳/无穷大
是.
如果遵循IEEE-754则:
其他陈述的规则可能不同.
2)有没有办法防止分裂导致无穷大
这应该在很大程度上防止:
#include <cfenv>
#include <cassert>
#include <cmath>
#include <limits>
// ...
static_assert(std::numeric_limits<decltype(x)>::is_iec559, "Unknown floating point standard.");
#pragma STDC FENV_ACCESS ON
int failed = std::fesetround(FE_TOWARDZERO);
assert(!failed);
if(x != 0 && std::isfinite(x) && std::isfinite(y))
return y / x;
else
throw std::invalid_argument("informative message");
Run Code Online (Sandbox Code Playgroud)
某些编译器可能需要非默认选项才能启用完全符合IEEE 754(-frounding-math在GCC上).
将非常小的数字除以非常大的数字,或者将两个非常大的数字相乘,可能会产生"无穷大".将无穷大除以另一个无穷大将产生NaN.例如,(1E300/1E-300)/(1E300/1E-300)或(1E300*1E300)/(1E300*1E300)两者都会产生NaN.
是的,请看下面的代码
#include <iostream>
int main ()
{
double x = 1, y = 2;
while (y != 0) {
std::cout << y << " " << x / y << std::endl;
y /= 2;
}
}
Run Code Online (Sandbox Code Playgroud)
在某个时刻你会得到:
8.9003e-308 1.12356e+307
4.45015e-308 2.24712e+307
2.22507e-308 4.49423e+307
1.11254e-308 8.98847e+307
5.56268e-309 inf
2.78134e-309 inf
1.39067e-309 inf
6.95336e-310 inf
Run Code Online (Sandbox Code Playgroud)