常用数学函数
对给定的浮点值分类
std::fpclassify
定义于头文件 |
||
#define fpclassify(arg) /* implementation defined */ |
(C99 起) |
归类浮点值 arg
到下列类别中:零、非正规、正规、无穷大、 NaN 或实现定义类别。该宏返回整数值。
忽略 FLT_EVAL_METHOD :即使以多于参数类型的范围和精度对它求值,首先仍将它转换到其语义类型,然后分类基于该类型:正规的 long double
值可能在转换到 double
时变为非正规,而在转换到 float
时变为零。
参数
arg | - | 浮点值 |
返回值
指明 arg
类别的 FP_INFINITE 、 FP_NAN 、 FP_NORMAL 、 FP_SUBNORMAL 、 FP_ZERO 或实现定义类型之一。
#define FP_NAN 0x0100
#define FP_NORMAL 0x0400
#define FP_INFINITE (FP_NAN | FP_NORMAL)
#define FP_ZERO 0x4000
#define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
可能实现
namespace GGX
{
using namespace std;
constexpr int
fpclassify(float __x)
{
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
FP_SUBNORMAL, FP_ZERO, __x);
}
constexpr int
fpclassify(double __x)
{
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
FP_SUBNORMAL, FP_ZERO, __x);
}
constexpr int
fpclassify(long double __x)
{
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
FP_SUBNORMAL, FP_ZERO, __x);
}
template<typename _Tp>
constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
int>::__type
fpclassify(_Tp __x)
{
return __x != 0 ? FP_NORMAL : FP_ZERO;
}
}
调用示例
#include <iostream>
#include <cstdlib>
#include <typeinfo>
#include <cinttypes>
#include <cmath>
#include <math.h>
#include <tgmath.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
const char *show_classification(double x)
{
//归类浮点值 arg 到下列类别中:零、非正规、正规、无穷大、 NaN 或实现定义类别。
switch (std::fpclassify(x))
{
case FP_INFINITE:
return "Inf";
case FP_NAN:
return "NaN";
case FP_NORMAL:
return "normal";
case FP_SUBNORMAL:
return "subnormal";
case FP_ZERO:
return "zero";
default:
return "unknown";
}
}
int main(void)
{
std::cout << "show_classification(1.0/0.0) is " << show_classification(1 / 0.0) << std::endl;
std::cout << "show_classification(0.0/0.0) is is " << show_classification(0.0 / 0.0) << std::endl;
std::cout << "show_classification(DBL_MIN/2) is is " << show_classification(DBL_MIN / 2) << std::endl;
std::cout << "show_classification(-0.0 is is) " << show_classification(-0.0) << std::endl;
std::cout << "show_classification(1.0 is is) " << show_classification(1.0) << std::endl;
std::cout << std::endl;
std::cout << "std::fpclassify(1.0/0.0) is " << std::fpclassify(1 / 0.0) << std::endl;
std::cout << "std::fpclassify(0.0/0.0) is is " << std::fpclassify(0.0 / 0.0) << std::endl;
std::cout << "std::fpclassify(DBL_MIN/2) is is " << std::fpclassify(DBL_MIN / 2) << std::endl;
std::cout << "std::fpclassify(-0.0) is " << std::fpclassify(-0.0) << std::endl;
std::cout << "std::fpclassify(1.0) is " << std::fpclassify(1.0) << std::endl;
std::cout << std::endl;
std::cout << std::hex;
std::cout << "std::fpclassify(1.0/0.0) is " << std::fpclassify(1 / 0.0) << std::endl;
std::cout << "std::fpclassify(0.0/0.0) is is " << std::fpclassify(0.0 / 0.0) << std::endl;
std::cout << "std::fpclassify(DBL_MIN/2) is is " << std::fpclassify(DBL_MIN / 2) << std::endl;
std::cout << "std::fpclassify(-0.0) is " << std::fpclassify(-0.0) << std::endl;
std::cout << "std::fpclassify(1.0) is " << std::fpclassify(1.0) << std::endl;
std::cout << std::endl;
printf("show_classification(1.0/0.0) is %s\n", show_classification(1 / 0.0));
printf("show_classification(0.0/0.0) is %s\n", show_classification(0.0 / 0.0));
printf("show_classification(DBL_MIN/2) is %s\n", show_classification(DBL_MIN / 2));
printf("show_classification(-0.0) is %s\n", show_classification(-0.0));
printf("show_classification(1.0) is %s\n", show_classification(1.0));
std::cout << std::endl;
return 0;
}
输出
show_classification(1.0/0.0) is Inf
show_classification(0.0/0.0) is is NaN
show_classification(DBL_MIN/2) is is subnormal
show_classification(-0.0 is is) zero
show_classification(1.0 is is) normal
std::fpclassify(1.0/0.0) is 1280
std::fpclassify(0.0/0.0) is is 256
std::fpclassify(DBL_MIN/2) is is 17408
std::fpclassify(-0.0) is 16384
std::fpclassify(1.0) is 1024
std::fpclassify(1.0/0.0) is 500
std::fpclassify(0.0/0.0) is is 100
std::fpclassify(DBL_MIN/2) is is 4400
std::fpclassify(-0.0) is 4000
std::fpclassify(1.0) is 400
show_classification(1.0/0.0) is Inf
show_classification(0.0/0.0) is NaN
show_classification(DBL_MIN/2) is subnormal
show_classification(-0.0) is zero
show_classification(1.0) is normal