相关疑难解决方法(0)

安静的NaN和信号NaN有什么区别?

我读过关于浮点的内容,我知道NaN可能来自操作.但我无法完全理解这些概念是什么.有什么区别?

在C++编程期间可以生成哪一个?作为程序员,我可以编写一个程序来导致sNaN吗?

floating-point nan ieee-754

81
推荐指数
2
解决办法
2万
查看次数

信号NaN的有用性?

我最近读了很多关于IEEE 754和x87架构的内容.我正在考虑在我正在研究的一些数值计算代码中使用NaN作为"缺失值",我希望使用信令 NaN将允许我在我不想要的情况下捕获浮点异常继续"缺失值".相反,我会使用安静的 NaN来允许"缺失值"通过计算传播.但是,信号NaN不起作用,因为我认为它们将基于它们上存在的(非常有限的)文档.

以下是我所知道的摘要(所有这些都使用x87和VC++):

  • _EM_INVALID(IEEE"无效"异常)在遇到NaN时控制x87的行为
  • 如果屏蔽了_EM_INVALID(禁用了异常),则不会生成异常,操作可以返回安静的NaN.涉及信令NaN的操作不会引发异常,但会转换为安静的NaN.
  • 如果_EM_INVALID未被屏蔽(启用了异常),则无效操作(例如,sqrt(-1))会导致抛出无效异常.
  • x87 从不生成信令NaN.
  • 如果_EM_INVALID是未屏蔽的,任何使用的信令的NaN(即使初始化与它的变量)的导致一个无效引发异常.

标准库提供了一种访问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寄存器以将其存储到存储器地址).

您可以像我一样思考以下内容:

  1. 掩码_EM_INVALID.
  2. 使用信令NaN初始化变量.
  3. Unmask_EM_INVALID.

但是,步骤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)

c++ floating-point ieee-754 visual-c++ x87

50
推荐指数
1
解决办法
1万
查看次数

当计算结果在运行时导致NaN或inf时,我可以让gcc告诉我吗?

有没有办法告诉gcc抛出一个SIGFPE或类似的东西来响应在运行时NaN(-)inf在运行时产生的计算,就像它会被零除?

我试过了-fsignaling-nans旗帜,似乎没什么帮助.

c floating-point gcc

18
推荐指数
2
解决办法
5805
查看次数

生成NaN浮点数时停止调试器

我有一个C++程序.在程序的某处(难以重现,但可重现),caclculation导致浮动设置为NaN.由于涉及NaN的浮点运算导致NaN,因此传播速度很快.

有什么方法可以设置编译器(gcc 4.4)或debuger(gdb)在浮点运算导致NaN时停止?那将非常有用.

谢谢!弥敦道

PS:可能很重要:我在ubuntu linux 10.10下工作.

c++ floating-point gdb nan

13
推荐指数
1
解决办法
6574
查看次数

诱捕安静的NaN

我有一个应用程序,其中一些组件偶尔在大数据流中插入qNaN,然后​​使整个处理无效(包含单个qNaN的向量上的FFT导致全qNaN输出).现在我想抓住行动中的那个组成部分,并找出它为什么这样做.

为此,我需要在调试期间以某种方式使所有NaN信令.有没有办法这样做,x64 CPU执行32位代码?

c++ debugging floating-point x86

13
推荐指数
2
解决办法
3940
查看次数

在没有代码更改的情况下生成NaN浮点数时停止调试器

我读到这个这个.如果通过包含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版编译器.

c c++ nan sigfpe

6
推荐指数
1
解决办法
216
查看次数

标签 统计

floating-point ×5

c++ ×4

nan ×3

c ×2

ieee-754 ×2

debugging ×1

gcc ×1

gdb ×1

sigfpe ×1

visual-c++ ×1

x86 ×1

x87 ×1