为啥 nan 可以通过重复计算来防止?

Posted

技术标签:

【中文标题】为啥 nan 可以通过重复计算来防止?【英文标题】:why is nan can be prevented by duplicated calculation?为什么 nan 可以通过重复计算来防止? 【发布时间】:2013-01-26 23:11:50 【问题描述】:

有时我得到一个 nan 作为乘法 no-nan b 和 c 的结果:

double a = b * c; //b = 0, c = 1024, a = nan

或者作为 floor() 的结果:

double a = floor(b); //b = 2024, a = nan

重复计算和使用 sleep() 可以防止这个问题:

a = b * c;  //a = nan
a = b * c;  //a = 0

a = floor(b);  //a = nan
a = floor(b);  //a = 2024

sleep(1);
a = b * c;  //a = 0

sleep(1);
a = floor(b);  //a = 2024

CPU 是 AMD Athlon(tm) 64 X2 Dual Core Processor 3400+

CPU 温度

k8temp-pci-00c3
Adapter: PCI adapter
Core0 Temp: -1В°C
Core0 Temp: -2В°C
Core1 Temp: +3В°C
Core1 Temp: +7В°C

Adapter: SMBus PIIX4 adapter at 0b00
M/B Temp:    +30В°C  (low  =    +0В°C, high =   +85В°C)   
CPU Temp:  +28.5В°C  (low  =  +0.0В°C, high = +85.0В°C)   
M/B Crit:    +85В°C  (hyst =   +75В°C)                  
CPU Crit:   +124В°C  (hyst =  +114В°C)   

这个问题可能是 CPU 计时功能的结果吗?还是有其他问题的原因?

更新

我发现以下程序在那台机器上产生了 nan:

double a, b, c;
while(1) 
   a = 0;
   b = 1024;
   c = a * b; //c will be nan within 10-20 sec.

【问题讨论】:

现在这确实很奇怪。 这绝对是机器特有的问题。你超频了吗?它的运行温度是多少? NAN 表示“不是数字”,它是非法浮点运算返回的结果。引用的都不符合条件。 我发现您不太可能从简单的乘法中得到 NaN,除非其中一个数字是:1) NaN,或 2) 相乘结果超出范围 (1E+/ -308 左右)。您的输入数据不正确,处理器运行超出规格[超频,冷却不足,内存损坏等]。 @MatsPetersson 即使这样:浮点运算的现代实现不应该将溢出作为 Inf 处理吗? 【参考方案1】:

您是否有可能在程序中的其他地方发生堆栈或内存覆盖 - 错误的线程处理或错误处理的互斥锁?添加睡眠来“修复”问题让我认为这可能是一个并发问题。如果可能,调试这些值并查看它们是否从其他位置动态更改,并通过写入内存断点或可能只是一些 printfs(这可能会改变问题的时间并将其隐藏。)

【讨论】:

证明这一点的最快方法是单独尝试你的场景。如果以整个程序为例,你仍然遇到同样的问题,那你就有麻烦了。 @MichaelDorgan 代码由 valgring 检查。它什么也没找到。这些变量是本地的。 如果你在线程等方面做了坏事,本地变量就没有任何意义。 valgrind 是一个很好的,但不是确定的检查。如果您的整个代码与问题中所述相同,您是否会遇到所述问题? @PhilipKendall 实际上,我在 libresample 库遇到了这个问题。 @Alex 你的内存有可能有缺陷吗?您是否尝试在启用优化的情况下编译您的代码?如果您使用 -Wall 进行编译,编译器是否会发出任何警告?【参考方案2】:

实际上,这是特定于硬件的问题。当前平台上的以下程序可以运行 10-20 秒:

#include <math.h>
int main() 
   double a, b, c;
   while (1) 
      a = 0;
      b = 1024;
      c = a * b;
      if (isnan(c)) break;
   
   return 0;

【讨论】:

顺便说一句:你#include &lt;math.h&gt; 吗?我的 gcc 生成没有 math.h 的内联代码,并使用 调用 __isnan @wildplasser,是的,math.h 应该包括在内。编辑我的帖子。

以上是关于为啥 nan 可以通过重复计算来防止?的主要内容,如果未能解决你的问题,请参考以下文章

如果输入值为 NaN,则返回零 [重复]

防止 pandas 将 None 读为 Nan

如何防止 NaN 值附加到 ArrayList?

利用Redis实现防止接口重复提交功能

为啥我的 React 应用程序不能使用我的 Apache .htaccess 文件来防止 404?

如何通过点击“返回”按钮来防止用户查看以前用户的信息[重复]