写点什么

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

作者:桑榆
  • 2022 年 9 月 11 日
    广东
  • 本文字数:1954 字

    阅读完需:约 6 分钟

续接上文:https://xie.infoq.cn/article/d8a58a793a310bcc0f1c7f098

比较函数、绝对值函数、最值函数的定义与功能分析。

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

比较两数的关系,给出 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.h1312 #  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
复制代码


发布于: 刚刚阅读数: 3
用户头像

桑榆

关注

北海虽赊,扶摇可接;东隅已逝,桑榆非晚! 2020.02.29 加入

Android手机厂商-相机软件系统工程师 爬山/徒步/Coding

评论

发布
暂无评论
C++学习------cmath头文件的源码学习04_c++_桑榆_InfoQ写作社区