我读过关于浮点的内容,我知道NaN可能来自操作.但我无法完全理解这些概念是什么.有什么区别?
在C++编程期间可以生成哪一个?作为程序员,我可以编写一个程序来导致sNaN吗?
我最近读了很多关于IEEE 754和x87架构的内容.我正在考虑在我正在研究的一些数值计算代码中使用NaN作为"缺失值",我希望使用信令 NaN将允许我在我不想要的情况下捕获浮点异常继续"缺失值".相反,我会使用安静的 NaN来允许"缺失值"通过计算传播.但是,信号NaN不起作用,因为我认为它们将基于它们上存在的(非常有限的)文档.
以下是我所知道的摘要(所有这些都使用x87和VC++):
标准库提供了一种访问NaN值的方法:
std::numeric_limits<double>::signaling_NaN();
Run Code Online (Sandbox Code Playgroud)
和
std::numeric_limits<double>::quiet_NaN();
Run Code Online (Sandbox Code Playgroud)
问题是我认为信号NaN没有任何用处.如果屏蔽了_EM_INVALID,则其行为与安静NaN完全相同.由于没有NaN与任何其他NaN相当,因此没有逻辑差异.
如果未屏蔽_EM_INVALID (启用异常),则甚至无法使用信号NaN初始化变量:
double dVal = std::numeric_limits<double>::signaling_NaN();因为这会引发异常(信号NaN值被加载到x87寄存器以将其存储到存储器地址).
您可以像我一样思考以下内容:
但是,步骤2会导致信令NaN转换为安静的NaN,因此后续使用它不会导致异常被抛出!那么WTF?!
信号NaN是否有任何实用性或目的?我理解其中一个原始意图是使用它初始化内存,以便可以捕获使用单位化浮点值.
有人能告诉我,如果我在这里遗失了什么吗?
编辑:
为了进一步说明我希望做的事情,这里有一个例子:
考虑对数据向量(双精度)执行数学运算.对于某些操作,我想允许向量包含"缺失值"(假设这对应于电子表格列,例如,其中一些单元格没有值,但它们的存在很重要).对于某些操作,我不希望允许向量包含"缺失值".如果集合中存在"缺失值",也许我想采取不同的行动 - 可能执行不同的操作(因此这不是无效的状态).
这个原始代码看起来像这样:
const double MISSING_VALUE = 1.3579246e123;
using std::vector;
vector<double> missingAllowed(1000000, MISSING_VALUE);
vector<double> missingNotAllowed(1000000, MISSING_VALUE);
// ... populate missingAllowed and missingNotAllowed with (user) data...
for (vector<double>::iterator it = missingAllowed.begin(); it != missingAllowed.end(); ++it) …Run Code Online (Sandbox Code Playgroud) 有没有办法告诉gcc抛出一个SIGFPE或类似的东西来响应在运行时NaN或(-)inf在运行时产生的计算,就像它会被零除?
我试过了-fsignaling-nans旗帜,似乎没什么帮助.
我有一个C++程序.在程序的某处(难以重现,但可重现),caclculation导致浮动设置为NaN.由于涉及NaN的浮点运算导致NaN,因此传播速度很快.
有什么方法可以设置编译器(gcc 4.4)或debuger(gdb)在浮点运算导致NaN时停止?那将非常有用.
谢谢!弥敦道
PS:可能很重要:我在ubuntu linux 10.10下工作.
我有一个应用程序,其中一些组件偶尔在大数据流中插入qNaN,然后使整个处理无效(包含单个qNaN的向量上的FFT导致全qNaN输出).现在我想抓住行动中的那个组成部分,并找出它为什么这样做.
为此,我需要在调试期间以某种方式使所有NaN信令.有没有办法这样做,x64 CPU执行32位代码?
我读到这个和这个.如果通过包含fenv.h生成nan并且启用所有浮点异常,则可以抛出SIGFPE,但是FE_INEXACT通过feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
因此,代码改变了形式
int main () {
double dirty = 0.0;
double nanvalue = 0.0/dirty;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
至
#include <fenv.h>
int main () {
feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT); // Enable all floating point exceptions but FE_INEXACT
double dirty = 0.0;
double nanvalue = 0.0/dirty;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但您必须更改代码.我有问题,在一个巨大的c和c ++代码库中,某个地方生成了一个nan,我不知道在哪里.将上述更改应用于文件的hunderts并跟踪错误不是一种选择.
有没有办法在没有代码更改的情况下启用所有浮点异常?有没有我不知道的编译选项?
我们使用intel icc 15.0.3版编译器.