国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

C標(biāo)準(zhǔn)庫源碼解剖(12):浮點(diǎn)數(shù)環(huán)境fenv.h

2024-07-10 13:27:18
字體:
供稿:網(wǎng)友

為了編寫高精度浮點(diǎn)數(shù)的運(yùn)算,編程人員需要控制浮點(diǎn)數(shù)環(huán)境的各個(gè)方面:結(jié)果如何舍入,浮點(diǎn)數(shù)表達(dá)式如何簡化與變換,如何處理浮點(diǎn)數(shù)異常(如下溢之類的浮點(diǎn)數(shù)異常是忽略還是產(chǎn)生錯(cuò)誤),等等。C99引入了fenv.h來控制浮點(diǎn)數(shù)環(huán)境。
    1、fenv.h: 定義了浮點(diǎn)數(shù)環(huán)境控制函數(shù)、異常控制函數(shù)、舍入方式控制函數(shù)、浮點(diǎn)數(shù)異常碼和舍入方式等。注意浮點(diǎn)數(shù)環(huán)境的實(shí)現(xiàn)是依賴于體系結(jié)構(gòu)的,因?yàn)椴煌捏w系結(jié)構(gòu)有不同的浮點(diǎn)數(shù)指令集。依賴于體系結(jié)構(gòu)的定義放在bits/fenv.h中,這里是x86體系結(jié)構(gòu)的版本(Linux下)。
    標(biāo)準(zhǔn)頭文件fenv.h內(nèi)容如下:

 

[cpp] view plaincopy
  1. /* ISO C99 7.6: 浮點(diǎn)數(shù)環(huán)境   <fenv.h> */  
  2. #ifndef _FENV_H  
  3. #define _FENV_H 1  
  4. #include <features.h>  
  5. /* 獲取依賴于體系結(jié)構(gòu)的定義。應(yīng)該要有下面這些定義: 
  6.    fenv_t   表示浮點(diǎn)數(shù)環(huán)境的類型 
  7.    FE_DFL_ENV   fenv_t *指針類型的值,表示浮點(diǎn)數(shù)環(huán)境的缺省值(用于需要fenv_t參數(shù)的函數(shù)中) 
  8.    fexcept_t    表示浮點(diǎn)數(shù)異常標(biāo)志(這個(gè)標(biāo)志保存了浮點(diǎn)數(shù)的狀態(tài))的類型 
  9.     下面的宏被定義,當(dāng)且僅當(dāng)實(shí)現(xiàn)支持這些宏時(shí): 
  10.    FE_INEXACT       不精確的結(jié)果 
  11.    FE_DIVBYZERO     除數(shù)為0 
  12.    FE_UNDERFLOW     結(jié)果向下溢出 
  13.    FE_OVERFLOW      結(jié)果向上溢出 
  14.    FE_INVALID       無效的運(yùn)算 
  15.    FE_ALL_EXCEPT    所有被支持的異常的按位或 
  16.    下面這些宏被定義,當(dāng)且僅當(dāng)實(shí)現(xiàn)支持某些適當(dāng)?shù)纳崛敕绞綍r(shí): 
  17.    FE_TONEAREST     最近舍入 
  18.    FE_UPWARD        向正無窮大(+Inf)舍入 
  19.    FE_DOWNWARD      向負(fù)無窮大(-Inf)舍入 
  20.    FE_TOWARDZERO    向0舍入 
  21. */  
  22. #include <bits/fenv.h>  
  23. __BEGIN_DECLS  
  24. /* 浮點(diǎn)數(shù)異常處理  */  
  25. /* 清除EXCEPTS表示的異常狀態(tài)  */  
  26. extern int feclearexcept (int __excepts) __THROW;  
  27. /* 將實(shí)現(xiàn)定義的異常標(biāo)志EXCEPTS保存到FLAGP所指的對象中 */  
  28. extern int fegetexceptflag (fexcept_t *__flagp, int __excepts) __THROW;  
  29. /* 產(chǎn)生由EXCEPTS表示的異常 */  
  30. extern int feraiseexcept (int __excepts) __THROW;  
  31. /* 根把EXCEPTS異常標(biāo)志設(shè)置為FLAGP所指對象中的值 */  
  32. extern int fesetexceptflag (__const fexcept_t *__flagp, int __excepts) __THROW;  
  33. /* 確定EXCEPTS指示的各個(gè)異常中有哪個(gè)異常子集被設(shè)置了 */  
  34. extern int fetestexcept (int __excepts) __THROW;  
  35. /* 舍入控制  */  
  36. /* 獲得當(dāng)前的舍入方向,表示為一個(gè)舍入方向宏值  */  
  37. extern int fegetround (void) __THROW;  
  38. /* 設(shè)置舍入方向,成功時(shí)返回0  */  
  39. extern int fesetround (int __rounding_direction) __THROW;  
  40. /* 浮點(diǎn)數(shù)環(huán)境  */  
  41. /* 獲取當(dāng)前的浮點(diǎn)數(shù)環(huán)境,并保存在ENVP所指的對象中 */  
  42. extern int fegetenv (fenv_t *__envp) __THROW;  
  43. /* 將當(dāng)前浮點(diǎn)數(shù)環(huán)境保存到ENVP所指對象中,清除異常標(biāo)志,然后安裝一個(gè)不停止的浮點(diǎn)數(shù)環(huán)境(即 
  44.     忽略所有浮點(diǎn)數(shù)異常) */  
  45. extern int feholdexcept (fenv_t *__envp) __THROW;  
  46. /* 設(shè)置浮點(diǎn)數(shù)環(huán)境 */  
  47. extern int fesetenv (__const fenv_t *__envp) __THROW;  
  48. /* 將當(dāng)前浮點(diǎn)數(shù)環(huán)境保存到一個(gè)臨時(shí)存儲中,然后安裝ENVP所指的環(huán)境,并根據(jù)保存的異常環(huán)境 
  49.     產(chǎn)生異常 */  
  50. extern int feupdateenv (__const fenv_t *__envp) __THROW;  
  51.   
  52. /* 下面包含了一些作為擴(kuò)展的優(yōu)化函數(shù)  */  
  53. #ifdef __OPTIMIZE__  
  54. # include <bits/fenvinline.h>  
  55. #endif  
  56. #ifdef __USE_GNU  
  57. /* 激活個(gè)別的異常,激活的個(gè)數(shù)不會多于EXCEPTS指示的異常個(gè)數(shù)。如果所有異常被成功設(shè)置,則返回 
  58.     以前激活的異常,否則返回-1 */  
  59. extern int feenableexcept (int __excepts) __THROW;  
  60. /* 禁用個(gè)別的異常,禁用的異常個(gè)數(shù)不會多于EXCEPTS指示的異常個(gè)數(shù)。如果所有異常被成功禁用, 
  61.     則返回先前激活的異常,否則返回-1 */  
  62. extern int fedisableexcept (int __excepts) __THROW;  
  63. /* 返回激活的異常  */  
  64. extern int fegetexcept (void) __THROW;  
  65. #endif  
  66. __END_DECLS  
  67. #endif /* fenv.h */  

 

    bits/fenv.h內(nèi)容如下:

 

[cpp] view plaincopy
  1. /* bits/fenv.h:定義了浮點(diǎn)數(shù)異常碼,x86體系結(jié)構(gòu)的版本(Linux下)  */  
  2. #ifndef _FENV_H  
  3. # error "Never use <bits/fenv.h> directly; include <fenv.h> instead."  
  4. #endif  
  5. #include <bits/wordsize.h>  
  6. /* 定義代表異常的位,我們使用FPU控制字中適當(dāng)?shù)奈?nbsp;*/  
  7. enum  
  8.   {  
  9.     FE_INVALID = 0x01,           /* 無效的運(yùn)算 */  
  10. #define FE_INVALID  FE_INVALID  
  11.     __FE_DENORM = 0x02,  
  12.     FE_DIVBYZERO = 0x04,        /* 除數(shù)為0 */  
  13. #define FE_DIVBYZERO    FE_DIVBYZERO  
  14.     FE_OVERFLOW = 0x08,        /* 結(jié)果向上溢出 */  
  15. #define FE_OVERFLOW FE_OVERFLOW  
  16.     FE_UNDERFLOW = 0x10,       /* 結(jié)果向下溢出 */  
  17. #define FE_UNDERFLOW    FE_UNDERFLOW  
  18.     FE_INEXACT = 0x20          /* 不精確的結(jié)果 */  
  19. #define FE_INEXACT  FE_INEXACT  
  20.   };  
  21. /* 所有異常的按位或 */  
  22. #define FE_ALL_EXCEPT /  
  23.     (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)  
  24. /* ix87 FPU支持所有四種已經(jīng)定義的舍入模式。我們又使用FPU控制字中位作為相應(yīng)宏的值 */  
  25. enum  
  26.   {  
  27.     FE_TONEAREST = 0,         /* 最近舍入 */  
  28. #define FE_TONEAREST    FE_TONEAREST  
  29.     FE_DOWNWARD = 0x400,  
  30. #define FE_DOWNWARD FE_DOWNWARD  
  31.     FE_UPWARD = 0x800,       /* 向負(fù)無窮舍入 */  
  32. #define FE_UPWARD   FE_UPWARD  
  33.     FE_TOWARDZERO = 0xc00    /* 向正無窮舍入 */  
  34. #define FE_TOWARDZERO   FE_TOWARDZERO  
  35.   };  
  36.   
  37. /* 代表異常標(biāo)志的類型  */  
  38. typedef unsigned short int fexcept_t;  
  39. /* 代表浮點(diǎn)數(shù)環(huán)境的類型。這個(gè)與塊的布局有關(guān)的結(jié)構(gòu)由fstenv指令寫入,并且有另外的域作為 
  40.    MXCSR寄存器的內(nèi)容,這個(gè)寄存器由stmxcsr指令寫入 */  
  41. typedef struct  
  42.   {  
  43.     unsigned short int __control_word;  
  44.     unsigned short int __unused1;  
  45.     unsigned short int __status_word;  
  46.     unsigned short int __unused2;  
  47.     unsigned short int __tags;  
  48.     unsigned short int __unused3;  
  49.     unsigned int __eip;  
  50.     unsigned short int __cs_selector;  
  51.     unsigned int __opcode:11;  
  52.     unsigned int __unused4:5;  
  53.     unsigned int __data_offset;  
  54.     unsigned short int __data_selector;  
  55.     unsigned short int __unused5;  
  56. #if __WORDSIZE == 64  
  57.     unsigned int __mxcsr;  
  58. #endif  
  59.   }  
  60. fenv_t;  
  61. /* 缺省的浮點(diǎn)數(shù)環(huán)境:使用下面這個(gè)值  */  
  62. #define FE_DFL_ENV  ((__const fenv_t *) -1)  
  63. #ifdef __USE_GNU  
  64. /* 沒有任何異常被屏蔽的浮點(diǎn)數(shù)環(huán)境  */  
  65. # define FE_NOMASK_ENV  ((__const fenv_t *) -2)  
  66. #endif  

 

    標(biāo)準(zhǔn)C中指定的接口有:
    (1)浮點(diǎn)數(shù)環(huán)境類型:fenv_t,是一個(gè)結(jié)構(gòu)體,里面的成員依賴于體系結(jié)構(gòu)。
    (2)浮點(diǎn)數(shù)環(huán)境的缺省值:FE_DFL_ENV,是一個(gè)fenv_t *指針類型的值(為-1),用于需要fenv_t參數(shù)的函數(shù)中。
    (3)浮點(diǎn)數(shù)異常標(biāo)志類型:fexcept_t,為unsigned short類型。異常標(biāo)志中保存了浮點(diǎn)數(shù)的狀態(tài)。
    (4)浮點(diǎn)數(shù)異常:FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW, FE_OVERFLOW, FE_INVALID, FE_ALL_EXCEPT。
    (5)浮點(diǎn)數(shù)舍入方式:FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO。
    (6)浮點(diǎn)數(shù)環(huán)境控制函數(shù):fegetenv, fesetenv, feholdexcpet, feupdateenv。
    (7)浮點(diǎn)數(shù)異常處理函數(shù):fegetexceptflag, fesetexceptflag, fetestexcept, feraiseexcept, feclearexcept。
    (8)浮點(diǎn)數(shù)舍入控制函數(shù):fegetround, fesetround。
    2、浮點(diǎn)數(shù)環(huán)境、異常、舍入控制函數(shù)的實(shí)現(xiàn): 這些函數(shù)的實(shí)現(xiàn)都是依賴于體系結(jié)構(gòu)的,x86體系結(jié)構(gòu)的部分在glibc源碼的sysdeps/i386/fpu目錄下。每個(gè)函數(shù)對應(yīng)一個(gè)C語言源文件,由于要用到浮點(diǎn)數(shù)操作指令,因此都嵌入了匯編代碼。這些函數(shù)的功能都非常簡單,主要是通過fenv_t的實(shí)例或fexcept_t的實(shí)例來獲取或設(shè)置相應(yīng)的值,因此代碼都不長,要理解這些代碼,主要是要對x86體系結(jié)構(gòu)有全面的了解。由于代碼依賴于體系結(jié)構(gòu),也沒有特別值得研究的獨(dú)立于體系結(jié)構(gòu)的算法,因此這里并不打算解剖它們的源代碼。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 张家港市| 辉县市| 阜平县| 崇义县| 石屏县| 花垣县| 静乐县| 华阴市| 中超| 密山市| 诸城市| 龙陵县| 阿拉尔市| 永济市| 弥勒县| 华安县| 安福县| 鄂尔多斯市| 莲花县| 清苑县| 南召县| 沙雅县| 亳州市| 凤翔县| 洞头县| 湖州市| 增城市| 临桂县| 永寿县| 平罗县| 沽源县| 论坛| 甘肃省| 六安市| 仙桃市| 乐亭县| 泌阳县| 广河县| 无极县| 乌拉特前旗| 玉山县|