前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浮点数环境 cfenv(fenv.h)

浮点数环境 cfenv(fenv.h)

作者头像
用户7886150
修改2021-02-09 16:42:51
6650
修改2021-02-09 16:42:51
举报
文章被收录于专栏:bit哲学院

参考链接: C++ fesetround()

在编写高精度浮点运算程序时,需要对浮点环境进行控制并捕获浮点环境异常。cfenv头文件定义了对浮点环境控制及异常相关的函数和宏。 

 注记  

  FENV_ACCESS 

 #pragma STDC FENV_ACCESS on //设置该参数表示可以访问浮点运算异常的状态值 

 #pragma STDC FENV_ACCESS off //设置该参数表示禁止访问浮点运算异常的状态值 

 浮点数异常处理  

 函数 

 /* 清除EXCEPTS表示的异常状态  */   

 int feclearexcept (int __excepts); 

 /* 产生由EXCEPTS表示的异常 */   

 int feraiseexcept (int __excepts) ; 

 /* 将实现定义的异常标志EXCEPTS保存到FLAGP所指的对象中 */   

  int fegetexceptflag (fexcept_t *__flagp, int __excepts) ;  

 /* 根把EXCEPTS异常标志设置为FLAGP所指对象中的值 */   

 int fesetexceptflag (__const fexcept_t *__flagp, int __excepts) ;  

 /* 确定EXCEPTS指示的各个异常中有哪个异常子集被设置了 */   

 int fetestexcept (int __excepts) ; 

 宏(int类型) 

  FE_INEXACT       精度丢失  

  FE_DIVBYZERO     除数为0  

  FE_UNDERFLOW     结果向下溢出  

  FE_OVERFLOW      结果向上溢出  

  FE_INVALID       无效的运算  

  FE_ALL_EXCEPT    所有被支持的异常的按位或 

 示例1 

   [cpp] 

   view plain

    copy 

  #include <stdio.h>      /* printf */   #include <fenv.h>       /* fegetround, FE_* */   #include <math.h>       /* rint */   void show_all_except(void);   int main ()   {       show_all_except();       double d = 1e-40;       float f;       f = d;//这种精度丢失在编译过程中编译器编译不会提示,运行也没有问题       show_all_except();       return 0;   }      void show_all_except(void)     {         //设置该参数表示可以访问浮点运算异常的状态值         #pragma STDC FENV_ACCESS ON          //获取所有可能的异常         int res = fetestexcept(FE_ALL_EXCEPT);                  printf( "Status: " );         if(res & FE_INEXACT)//判断是否有精度损失的异常         {             printf( " inexact ");         }         if(res & FE_UNDERFLOW)//判断是否有下溢         {             printf( " underflow ");         }         if(res & FE_OVERFLOW)//判断是否有上溢         {             printf( " overflow ");         }         if(res & FE_DIVBYZERO)//判断是否有被0除         {             printf( " zero-divide ");         }         if(res & FE_INVALID)//判断是否有不合法的浮点运算         {             printf( " invalid ");         }         printf( " \n ");     }    

 运行结果 

   [cpp] 

   view plain

    copy 

  Status:   Status:  inexact  underflow   

 高精度编程时,可以通过这些函数检查是否存在异常,并进行相应处理。 

 舍入控制   

 函数 

 /* 获得当前的舍入方向,表示为一个舍入方向宏值  */   

 int fegetround (void) ; 

 /* 设置舍入方向,成功时返回0  */   

 int fesetround (int __rounding_direction) ; 

宏(int类型)

 FE_TONEAREST     最近舍入  FE_UPWARD        向正无穷大(+Inf)舍入  FE_DOWNWARD      向负无穷大(-Inf)舍入  FE_TOWARDZERO    向0舍入  

 示例2 

   [cpp] 

   view plain

    copy 

  #include <stdio.h>      /* printf */   #include <fenv.h>       /* fegetround, FE_* */   #include <math.h>       /* rint */   void printfRounding();   int main ()   {       printfRounding();       printf ( "rint (2.49) = %.1f\n", rint(2.49) );       printf ( "rint (3.50) = %.1f\n", rint(3.50) );       fesetround(FE_TOWARDZERO);       printfRounding();       printf ( "rint (2.49) = %.1f\n", rint(2.49) );       printf ( "rint (3.50) = %.1f\n", rint(3.50) );       return 0;   }   void printfRounding()   {       printf ("now rounding using: ");       switch (fegetround()) {           case FE_DOWNWARD: printf ("downward"); break;           case FE_TONEAREST: printf ("to-nearest"); break;           case FE_TOWARDZERO: printf ("toward-zero"); break;           case FE_UPWARD: printf ("upward"); break;           default: printf ("unknown");       }       printf("\n");   }   

运行结果: 

   [cpp] 

   view plain

    copy 

  now rounding using: to-nearest   rint (2.49) = 2.0   rint (3.50) = 4.0   now rounding using: toward-zero   rint (2.49) = 2.0   rint (3.50) = 3.0   

  浮点数环境 

 函数 

  /* 获取当前的浮点数环境,并保存在ENVP所指的对象中 */  

  int fegetenv (fenv_t *__envp) ; 

  /* 设置浮点数环境 */  

  int fesetenv (__const fenv_t *__envp);

  /* 将当前浮点数环境保存到ENVP所指对象中,清除异常标志,然后安装一个无异常的浮点数环境 */  

  int feholdexcept (fenv_t *__envp) ; 

  /*没整明白*/ 

 int feupdateenv (__const fenv_t *__envp) ; 

 类型 

 fenv_t   表示浮点数环境的类型  

 fexcept_t    表示浮点数异常标志(这个标志保存了浮点数的状态)的类型 

 宏(fenv_t *指针类型) 

 FE_DFL_ENV  表示浮点数环境的缺省值(用于需要fenv_t参数的函数中) 

示例3:

(本示例中用到了两个打印函数分别在示例1、示例2中定义)

   [cpp] 

   view plain

    copy 

  #include <stdio.h>      /* printf */   #include <fenv.h>       /* fegetround, FE_* */   #include <math.h>       /* rint */   void printfRounding();   void show_all_except(void);   int main ()   {       fenv_t fe;       printfRounding();//打印当前Rounding规则       show_all_except();//打印当前异常状态       fesetround(FE_TOWARDZERO);//设置Rounding规则为向0靠近       feraiseexcept(FE_INEXACT);//注册一个精度丢失异常       printfRounding();//重新打印当前Rounding规则       show_all_except();//重新打印当前异常状态       fegetenv(&fe);//获取当前浮点环境       fesetenv(FE_DFL_ENV);//设置浮点环境为默认值       printfRounding();//重新打印当前Rounding规则       show_all_except();//重新打印当前异常状态       fesetenv(&fe);//设置浮点环境为上次保存的浮点环境       printfRounding();//重新打印当前Rounding规则       show_all_except();//重新打印当前异常状态       feraiseexcept(FE_OVERFLOW);//注册一个结果向上溢出异常       feholdexcept(&fe);//保存当前浮点环境,并清除所有异常       printfRounding();//重新打印当前Rounding规则       show_all_except();//重新打印当前异常状态       fesetenv(&fe);//设置浮点环境为上次保存的浮点环境       printfRounding();//重新打印当前Rounding规则       show_all_except();//重新打印当前异常状态       return 0;   }   

运行结果 

   [cpp] 

   view plain

    copy 

  now rounding using: to-nearest   Status:    now rounding using: toward-zero   Status:  inexact    now rounding using: to-nearest   Status:    now rounding using: toward-zero   Status:  inexact    now rounding using: toward-zero   Status:    now rounding using: toward-zero   Status:  inexact  overflow

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档