C++学习------cmath头文件的源码学习04

294 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情 续接上文:cmath头文件的源码学习03

宏函数定义---比较函数

比较两数的关系,给出bool判断结果

305  #define isgreater(x, y) __builtin_isgreater((x), (y))
306  #define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
307  #define isless(x, y) __builtin_isless((x), (y))
308  #define islessequal(x, y) __builtin_islessequal((x), (y))
309  #define islessgreater(x, y) __builtin_islessgreater((x), (y))
310  #define isunordered(x, y) __builtin_isunordered((x), (y))

isgreater---返回x是否大于y

isgreaterequal---返回x是否大于等于y

isless---返回x是否小于y

islessequal---返回x是否小于等于y

islessgreater---返回x是否小于或者大于y

isunordered---返回x和y是否不可排序(即判断x,y中是否有Nan)

上面是这几个函数的解释,我们来看看glibc中非内建函数的解释: 其中isunordered的判断是将两数相比较,如果其中有一个Nan那么两者一定不相等,同时判断两数自身和自身是否相等,Nan数是没法做这个判断的,所以返回true,这样就说明只要有一个数为Nan,那么isunordered就会返回true;

其它函数的判断中,也是结合了isunordered的结果的,只有可排序的数才能比较大小,所以如果有Nan数,那么之前的所有比较函数都会返回false,这一点要注意。

//glibc/math/math.h
1312 #  define isgreater(x, y) \
1313   (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
1314             !isunordered (__x, __y) && __x > __y; }))
1315 #  define isgreaterequal(x, y) \
1316   (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
1317             !isunordered (__x, __y) && __x >= __y; }))
1318 #  define isless(x, y) \
1319   (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
1320             !isunordered (__x, __y) && __x < __y; }))
1321 #  define islessequal(x, y) \
1322   (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
1323             !isunordered (__x, __y) && __x <= __y; }))
1324 #  define islessgreater(x, y) \
1325   (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
1326             !isunordered (__x, __y) && __x != __y; }))
1327 /* isunordered must always check both operands first for signaling NaNs.  */
1328 #  define isunordered(x, y) \
1329   (__extension__ ({ __typeof__ (x) __u = (x); __typeof__ (y) __v = (y); \
1330             __u != __v && (__u != __u || __v != __v); }))

函数族定义---绝对值函数fabs与abs

后续的函数都有三个类似的,对应double类型,float类型,long double类型,我们分析其中的double类型就好。

189  double fabs(double __x) __attribute_const__;
190  float fabsf(float __x) __attribute_const__;
191  long double fabsl(long double __x) __RENAME_LDBL(fabs, 3, 3) __attribute_const__;

后面C++11又增加了一个函数,通过函数重载,可以接受int型输入

     double fabs (double x);
      float fabs (float x);
long double fabs (long double x);
     double fabs (T x);           // additional overloads for integral types

函数族定义---fma乘加法,返回x*y+z的值

     double fma (double x     , double y     , double z);
      float fma (float x      , float y      , float z);
long double fma (long double x, long double y, long double z);
     double fma (Type1 x      , Type2 y      , Type3 z);       // additional overloads

函数族定义---fmax,返回两数中较大的那一个

     double fmax (double x     , double y);
      float fmax (float x      , float y);
long double fmax (long double x, long double y);
     double fmax (Type1 x      , Type2 y);       // additional overloads

函数族定义---fmin,返回两数中较小的那一个

     double fmin (double x     , double y);
      float fmin (float x      , float y);
long double fmin (long double x, long double y);
     double fmin (Type1 x      , Type2 y);       // additional overloads

函数族定义---fdim,如果x>y,返回x-y的值,其它情况都返回0

     double fdim (double x     , double y);
      float fdim (float x      , float y);
long double fdim (long double x, long double y);
     double fdim (Type1 x      , Type2 y);       // additional overloads

其它函数见后续分析