博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
转:浮点数环境 cfenv(fenv.h)
阅读量:5283 次
发布时间:2019-06-14

本文共 4922 字,大约阅读时间需要 16 分钟。

转:浮点数环境 cfenv(fenv.h)

https://blog.csdn.net/lion_hbeu/article/details/24013095

 

在编写高精度浮点运算程序时,需要对浮点环境进行控制并捕获浮点环境异常。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

#include 
/* printf */ #include
/* fegetround, FE_* */ #include
/* 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 "); }

 

运行结果

  1. Status:
  2. 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

#include 
/* printf */ #include
/* fegetround, FE_* */ #include
/* 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"); }

 

运行结果:

  1. now rounding
    using: to-nearest
  2. rint (2.49) = 2.0
  3. rint (
    3.50) = 4.0
  4. now rounding
    using: toward-zero
  5. rint (
    2.49) = 2.0
  6. 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中定义)

#include 
/* printf */ #include
/* fegetround, FE_* */ #include
/* 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; }

 

运行结果

    1. now rounding
      using: to-nearest
    2. Status:
    3. now rounding
      using: toward-zero
    4. Status: inexact
    5. now rounding
      using: to-nearest
    6. Status:
    7. now rounding
      using: toward-zero
    8. Status: inexact
    9. now rounding
      using: toward-zero
    10. Status:
    11. now rounding
      using: toward-zero
    12. Status: inexact overflow

转载于:https://www.cnblogs.com/igfirstblog/p/9412541.html

你可能感兴趣的文章
(五十四)涂鸦的实现和截图的保存
查看>>
配置EditPlus使其可以编译运行java程序
查看>>
java中的占位符\t\n\r\f
查看>>
MySQL通过frm 和 ibd 恢复数据过程
查看>>
SRS源码——Listener
查看>>
Java面向对象抽象类案例分析
查看>>
对SPI、IIC、IIS、UART、CAN、SDIO、GPIO的解释
查看>>
Thymeleaf模板格式化LocalDatetime时间格式
查看>>
庖丁解“学生信息管理系统”
查看>>
Pyltp使用
查看>>
其他ip无法访问Yii的gii,配置ip就可以
查看>>
php做的一个简易爬虫
查看>>
x的x次幂的值为10,求x的近似值
查看>>
jquery获取html元素的绝对位置和相对位置的方法
查看>>
ios中webservice报文的拼接
查看>>
Power BI 报告的评论服务支持移动设备
查看>>
ACdream 1068
查看>>
HDU 2665 Kth number
查看>>
记叙在人生路上对你影响最大的三位老师
查看>>
002.大数据第二天
查看>>