相关疑难解决方法(0)

检查C++中的double(或float)是否为NaN

是否有isnan()函数?

PS.:我在MinGW(如果这有所不同).

我不得不用isnan()从此解决了<math.h>,这是不存在的<cmath>,这让我#include在第一荷兰国际集团.

c++ double nan

358
推荐指数
12
解决办法
35万
查看次数

信号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万
查看次数

如何在C++中跟踪NaN

我将使用C++进行一些数学计算.输入浮点数是有效数字,但在计算之后,结果值为NaN.我想跟踪NaN值出现的点(可能使用GDB),而不是isNan()在代码中插入很多.但我发现即使是这样的代码也不会在出现NaN值时触发异常.

double dirty = 0.0;
double nanvalue = 0.0/dirty;
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议一种跟踪NaN或将NaN变为异常的方法吗?

c++ debugging floating-point

30
推荐指数
2
解决办法
9389
查看次数

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

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

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

c floating-point gcc

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

Visual Studio:在内存ACCESS设置数据断点(即数据为READ时)

我真的需要弄清楚我的Fortran项目何时读取向量的元素.我每天都使用数据断点,但是当我的代码访问(即读取)内存地址时,我找不到设置数据断点的方法,而我总是将其设置为在修改地址时断开.有没有办法在Visual Studio 2010上执行此操作?(我使用intel visual fortran撰写XE 2011作为编译器).或者更新到更新的视觉工作室?就像一个注释,我在这里看到gdb这样做我可以在GDB中的'内存访问'上设置一个断点吗? 谢谢.

Ps:我从GDB发送电子邮件,他们说不可能用它来做.请看下面的答案:

您好,目前创建的观察点类型是硬编码为"写入".这是因为Visual Studio不支持其他类型的观察点(在GUI和基础结构中).也许有可能在GDB控制台中启用读取观察点,但是它也需要一个黑客,因为控制台实际上"通过"Visual Studio工作(它不直接将命令传递给GDB).我也不确定这个功能是否真的适用于GDB.GDB有很多命令,它们的目标范围非常有限,例如它们只适用于单线程程序,或者仅适用于Linux而不适用于使用gdbserver等.读取观察点看起来像是一种非常依赖于平台的机制.请检查您的平台GDB是否支持读取观察点.如果此功能对您至关重要,请告诉我们.

最好的祝福

breakpoints visual-studio-2010

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