zoukankan      html  css  js  c++  java
  • 检查 NaN 数据值 (C/C++/Python 实现)

      NaN 是 Not a Number 的缩写.它是一个数值类型值,通常在浮点计算中,表示未定义或无法表示的值.而且,不能直接使用相等运算符 (==) 检查 NaN.由于在程序中,nan == nan (C/C++/Python) 或 nan is nan (Python) 总是返回 0 或 False.因此,除了采用库函数外,往往可以利用这个性质检查某个数值是否为 NaN.下面介绍如何采用库函数检查 NaN 值:

    C/C++ 实现

    在 C/C++ 中,采用 math.h 标准函数库中的 isnan 宏或函数检查 nan 值,具体示例代码如下:

    C 代码 test-nan.c

    /* isnan example */
    #include <stdio.h>      /* printf */
    #include <math.h>       /* isnan, sqrt */
    
    int main()
    {
      printf ("isnan(0.0)       : %d
    ",isnan(0.0));
      printf ("isnan(1.0/0.0)   : %d
    ",isnan(1.0/0.0));
      printf ("isnan(-1.0/0.0)  : %d
    ",isnan(-1.0/0.0));
      printf ("isnan(sqrt(-1.0)): %d
    ",isnan(sqrt(-1.0)));
      return 0;
    }

    编译和运行结果,如下所示

    $ gcc test-nan.c -lm
    $ ./a.out
    isnan(0.0)       : 0
    isnan(1.0/0.0)   : 0
    isnan(-1.0/0.0)  : 0
    isnan(sqrt(-1.0)): 1

    C++ 代码 test-nan.cpp

    /* isnan example */
    #include <cmath>       /* isnan, sqrt */
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      cout << "isnan(0.0)       : " << isnan(0.0) << endl;
      cout << "isnan(1.0/0.0)   : " << isnan(1.0/0.0) << endl;
      cout << "isnan(-1.0/0.0)  : " << isnan(-1.0/0.0) << endl;
      cout << "isnan(sqrt(-1.0)): " << isnan(sqrt(-1.0)) << endl;
    
      return 0;
    }

    编译和运行结果,如下所示

    $ g++ test-nan.cpp 
    $ ./a.out
    isnan(0.0)       : 0
    isnan(1.0/0.0)   : 0
    isnan(-1.0/0.0)  : 0
    isnan(sqrt(-1.0)): 1

    如果在编译时增加 -std=c++11 ,采用C++ 2011标准编译程序,可能会出现如下错误:

    $ g++ test-nan.cpp -std=c++11
    ...
    error: call of overloaded ‘isnan(double)’ is ambiguous
    ...

    一个简单的解决方法是在所有的 isnan 宏或函数前,增加域操作符( :: ),修改后的示例代码如下:

    /* isnan example */
    #include <cmath>       /* isnan, sqrt */
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      cout << "isnan(0.0)       : " << ::isnan(0.0) << endl;
      cout << "isnan(1.0/0.0)   : " << ::isnan(1.0/0.0) << endl;
      cout << "isnan(-1.0/0.0)  : " << ::isnan(-1.0/0.0) << endl;
      cout << "isnan(sqrt(-1.0)): " << ::isnan(sqrt(-1.0)) << endl;
    
      return 0;
    }

    保存后,重新编译运行即可.

    Python 实现

    Python 采用 numpy 数值数学库函数 np.isnan 检查 nan 值,示例代码 test-nan.py 如下:

    #!/usr/bin/env python
    # -*- coding: utf8 -*-
    # author: klchang
    from __future__ import print_function
    
    import numpy as np
    
    print ("isnan(0.0)       : ", np.isnan(0.0))
    print ("isnan(1.0/0.0)   : ", np.isnan(np.true_divide(1.0, 0.0)))
    print ("isnan(-1.0/0.0)  : ", np.isnan(np.true_divide(-1.0, 0.0)))
    print ("isnan(sqrt(-1.0)): ", np.isnan(np.sqrt(-1.0)))

    运行输出结果,如下:

    $ python test-nan.py
    isnan(0.0)       :  False
    ...: RuntimeWarning: divide by zero encountered in true_divide
      print ("isnan(1.0/0.0)   : ", np.isnan(np.true_divide(1.0, 0.0)))
    isnan(1.0/0.0)   :  False
    ...: RuntimeWarning: divide by zero encountered in true_divide
      print ("isnan(-1.0/0.0)  : ", np.isnan(np.true_divide(-1.0, 0.0)))
    isnan(-1.0/0.0)  :  False
    ...: RuntimeWarning: invalid value encountered in sqrt
      print ("isnan(sqrt(-1.0)): ", np.isnan(np.sqrt(-1.0)))
    isnan(sqrt(-1.0)):  True

    参考资料

    1. isnan macro/function - <cmath> reference. http://www.cplusplus.com/reference/cmath/isnan/

    2. NaN - Wikipedia, the free encyclopedia. https://en.wikipedia.org/wiki/NaN

    3. numpy isnan - NumPy Manual. https://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html

    4. Why is isnan ambigous and how to avoid it? - stackoverflow. https://stackoverflow.com/questions/33770374/why-is-isnan-ambiguous-and-how-to-avoid-it

  • 相关阅读:
    openstack 部署(Q版)keystone认证服务安装配置
    git仓库创建及基本使用
    saltstackmaster迁移篇
    openstack 部署(Q版)Mysql、MQ、Memcached安装配置
    saltstack安装篇
    openstack 部署(Q版)glance镜像服务安装配置
    openstack 部署(Q版)环境准备篇
    saltstack上线环境篇(一)
    ELKelasticsearch7.10.1安装配置
    记一次centos7内核可能意外丢失(测试直接干掉)恢复方法
  • 原文地址:https://www.cnblogs.com/klchang/p/9029658.html
Copyright © 2011-2022 走看看