C語言標(biāo)準(zhǔn)庫<math.h>和<setjmp.h>的實(shí)現(xiàn)
<math.h>
簡介
<math.h> 是 C 標(biāo)準(zhǔn)庫中的一個(gè)頭文件,主要提供了數(shù)學(xué)運(yùn)算相關(guān)的函數(shù)和宏定義。它允許您在 C 程序中執(zhí)行各種常見的數(shù)學(xué)計(jì)算,如三角函數(shù)、對(duì)數(shù)、指數(shù)、冪運(yùn)算等。
庫宏
下面是這個(gè)庫中定義的唯一的一個(gè)宏:
HUGE_VAL 是 <math.h> 頭文件中定義的一個(gè)宏,用于表示一個(gè)特定的很大的值。當(dāng)數(shù)學(xué)函數(shù)的結(jié)果無法表示為浮點(diǎn)數(shù)時(shí),可以使用 HUGE_VAL 來表示超出范圍的結(jié)果。
具體來說,如果函數(shù)的結(jié)果幅度太大以至于無法表示,則函數(shù)會(huì)將 errno 設(shè)置為 ERANGE,表示范圍錯(cuò)誤,并返回 HUGE_VAL 或 -HUGE_VAL。這允許您判斷函數(shù)是否返回了一個(gè)超出可表示范圍的值。
另一方面,如果函數(shù)的結(jié)果幅度太小,則可能會(huì)返回零值。在這種情況下,errno 可能被設(shè)置為 ERANGE,也可能不被設(shè)置為 ERANGE。因此,在使用數(shù)學(xué)函數(shù)并處理其返回值時(shí),需要注意檢查 errno 的值是否指示了錯(cuò)誤。
總之,HUGE_VAL 宏對(duì)于處理超出可表示范圍的數(shù)值是非常有用的,可以幫助進(jìn)行錯(cuò)誤處理和邊界檢查。
庫函數(shù)
下面列出了頭文件 math.h 中定義的函數(shù):
double acos(double x):返回以弧度表示的 x 的反余弦。
double asin(double x):返回以弧度表示的 x 的反正弦。
double atan(double x):返回以弧度表示的 x 的反正切。
double atan2(double y, double x):返回以弧度表示的 y/x 的反正切。y 和 x 的值的符號(hào)決定了正確的象限。
double cos(double x):返回弧度角 x 的余弦。
double cosh(double x):返回 x 的雙曲余弦。
double sin(double x):返回弧度角 x 的正弦。
double sinh(double x):返回 x 的雙曲正弦。
double tanh(double x):返回 x 的雙曲正切。
double exp(double x):返回 e 的 x 次冪的值。
double frexp(double x, int *exponent):把浮點(diǎn)數(shù) x 分解成尾數(shù)和指數(shù)。返回值是尾數(shù),并將指數(shù)存入 exponent 中。所得的值是 x = mantissa * 2 ^ exponent。
double ldexp(double x, int exponent):返回 x 乘以 2 的 exponent 次冪。
double log(double x):返回 x 的自然對(duì)數(shù)(基數(shù)為 e 的對(duì)數(shù))。
double log10(double x):返回 x 的常用對(duì)數(shù)(基數(shù)為 10 的對(duì)數(shù))。
double modf(double x, double *integer):返回值為小數(shù)部分(小數(shù)點(diǎn)后的部分),并設(shè)置 integer 為整數(shù)部分。
double pow(double x, double y):返回 x 的 y 次冪。
double sqrt(double x):返回 x 的平方根。
double ceil(double x):返回大于或等于 x 的最小的整數(shù)值。
double fabs(double x):返回 x 的絕對(duì)值。
double floor(double x):返回小于或等于 x 的最大的整數(shù)值。
double fmod(double x, double y):返回 x 除以 y 的余數(shù)。
實(shí)例
以下是一個(gè)簡單的代碼示例,展示了如何使用 <math.h> 頭文件中的一些函數(shù)來進(jìn)行數(shù)學(xué)計(jì)算:
#include <stdio.h> #include <math.h> // 引入 math.h 頭文件 int main() { double x = 1.5; double y = 2.7; // 計(jì)算 x 的雙曲正弦值和反正切值 double sinh_x = sinh(x); double atan_x = atan(x); // 計(jì)算 x 的立方根和以 2 為底的對(duì)數(shù) double cbrt_x = cbrt(x); double log2_x = log2(x); // 計(jì)算 y 的向下取整值和 x 與 y 的余數(shù) double floor_y = floor(y); double fmod_xy = fmod(x, y); // 打印計(jì)算結(jié)果 printf("sinh(%.2f) = %.2f\n", x, sinh_x); printf("atan(%.2f) = %.2f\n", x, atan_x); printf("cbrt(%.2f) = %.2f\n", x, cbrt_x); printf("log2(%.2f) = %.2f\n", x, log2_x); printf("floor(%.2f) = %.2f\n", y, floor_y); printf("%.2f %% %.2f = %.2f\n", x, y, fmod_xy); return 0; }
需要注意的是,這些函數(shù)在使用的時(shí)候需要特別小心,因?yàn)樗鼈冇锌赡軙?huì)產(chǎn)生一些異常情況(例如超出計(jì)算機(jī)數(shù)值范圍等)。
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生下列結(jié)果:
sinh(1.50) = 2.13
atan(1.50) = 0.98
cbrt(1.50) = 1.14
log2(1.50) = 0.58
floor(2.70) = 2.00
1.50 % 2.70 = 1.50
<setjmp.h>
簡介
<setjmp.h> 是 C 標(biāo)準(zhǔn)庫中的一個(gè)頭文件,提供了一種非局部跳轉(zhuǎn)的機(jī)制,允許程序在一個(gè)函數(shù)中設(shè)置一個(gè)跳轉(zhuǎn)點(diǎn),并在另一個(gè)函數(shù)中跳轉(zhuǎn)到該點(diǎn)。
庫變量
<setjmp.h> 頭文件并沒有定義任何變量。只定義了 jmp_buf 類型作為 setjmp 和 longjmp 函數(shù)的參數(shù)類型。jmp_buf 是一個(gè)用于存儲(chǔ)跳轉(zhuǎn)點(diǎn)信息的數(shù)組類型,具體的實(shí)現(xiàn)細(xì)節(jié)是未定義的,通常被編譯器實(shí)現(xiàn)為一個(gè)足夠大的數(shù)組。
請(qǐng)注意,雖然 <setjmp.h> 中沒有定義變量,但您可以在程序中創(chuàng)建自己的 jmp_buf 變量,并將其傳遞給 setjmp 和 longjmp 函數(shù)來實(shí)現(xiàn)非局部跳轉(zhuǎn)的功能。
庫函數(shù)
<setjmp.h> 頭文件中定義了兩個(gè)函數(shù):setjmp 和 longjmp,用于實(shí)現(xiàn)非局部跳轉(zhuǎn)和異常處理機(jī)制。
1、int setjmp(jmp_buf env) 函數(shù)
該函數(shù)將調(diào)用它的地方的當(dāng)前執(zhí)行狀態(tài)保存在 env 中,并返回 0。如果 setjmp 是由 longjmp 跳轉(zhuǎn)回來的,則返回一個(gè)非零值。
2、void longjmp(jmp_buf env, int val) 函數(shù)
該函數(shù)根據(jù)傳遞的 env 參數(shù),恢復(fù)相應(yīng)的執(zhí)行狀態(tài),并跳轉(zhuǎn)到相應(yīng)的位置。val 參數(shù)是返回到 setjmp 的返回值。
這兩個(gè)函數(shù)一起提供了非常有用的異常處理機(jī)制,通常用于處理錯(cuò)誤或異常情況,以及在程序中實(shí)現(xiàn)類似于異常處理的功能。
使用 <setjmp.h> 頭文件時(shí),需要注意以下幾點(diǎn):
- setjmp 和 longjmp 必須在同一個(gè)函數(shù)調(diào)用鏈中使用,而且 setjmp 必須在 longjmp 之前調(diào)用。
- jmp_buf 類型是一個(gè)數(shù)組類型,它存儲(chǔ)了用于保存執(zhí)行狀態(tài)的信息。然而,具體的實(shí)現(xiàn)細(xì)節(jié)是未定義的,因此不能直接訪問 jmp_buf 的成員。
- 使用 setjmp 和 longjmp 時(shí)應(yīng)謹(jǐn)慎,因?yàn)樗鼈儠?huì)導(dǎo)致程序的控制流程變得復(fù)雜,并且可能使代碼更難理解和維護(hù)。
需要注意的是,<setjmp.h> 頭文件提供了一種非常底層的編程機(jī)制,一般情況下并不推薦頻繁使用。
實(shí)例
#include <stdio.h> #include <setjmp.h> jmp_buf exception_env; // 用于保存執(zhí)行狀態(tài)的全局變量 void handle_exception() { printf("捕獲到異常,進(jìn)行異常處理\n"); } void do_something_dangerous(int input) { if (input < 0) { longjmp(exception_env, 1); // 跳轉(zhuǎn)到異常處理代碼 } else { printf("正常處理輸入:%d\n", input); } } int main() { if (setjmp(exception_env) == 0) { // 設(shè)置異常跳轉(zhuǎn)點(diǎn) // 正常情況 do_something_dangerous(10); do_something_dangerous(-5); // 這里會(huì)觸發(fā)異常 do_something_dangerous(20); // 這里不會(huì)執(zhí)行 } else { // 異常處理 handle_exception(); } return 0; }
讓我們編譯并運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
正常處理輸入:10
捕獲到異常,進(jìn)行異常處理
這個(gè)示例中定義了一個(gè)全局的 jmp_buf 類型的變量 exception_env,用于保存執(zhí)行狀態(tài)。在 main 函數(shù)中,通過 setjmp 設(shè)置了一個(gè)異常跳轉(zhuǎn)點(diǎn),并在 do_something_dangerous 函數(shù)中對(duì)輸入進(jìn)行判斷,如果輸入小于 0,則調(diào)用 longjmp 跳轉(zhuǎn)到異常處理代碼。在跳轉(zhuǎn)回來后,程序可以進(jìn)行相應(yīng)的異常處理。
需要注意的是,setjmp 和 longjmp 是比較底層的機(jī)制,使用時(shí)需要特別小心,因?yàn)樗鼈儠?huì)使程序的控制流程變得復(fù)雜,也容易引入難以調(diào)試的錯(cuò)誤。
到此這篇關(guān)于C語言標(biāo)準(zhǔn)庫<math.h>和<setjmp.h>的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語言 <math.h>和<setjmp.h>內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Qt實(shí)現(xiàn)可拖動(dòng)自定義控件
這篇文章主要為大家詳細(xì)介紹了如何基于Qt實(shí)現(xiàn)可拖動(dòng)自定義控件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下2023-04-04C++插件化 NDD源碼的插件機(jī)制實(shí)現(xiàn)解析
這篇文章主要介紹了C++插件化 NDD源碼的插件機(jī)制實(shí)現(xiàn)解析,這里再介紹推薦下優(yōu)秀的國產(chǎn)軟件開源項(xiàng)目?NDD(notepad--),一個(gè)支持windows/linux/mac的文本編輯器,目標(biāo)是要國產(chǎn)替換同類軟件,需要的朋友可以參考下2023-03-03C++用指針變量作為函數(shù)的參數(shù)接受數(shù)組的值的問題詳細(xì)總結(jié)
以下是對(duì)C++中用指針變量作為函數(shù)的參數(shù)接受數(shù)組的值的問題進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-10-10C++入門概覽和嘗試創(chuàng)建第一個(gè)C++程序
這篇文章主要介紹了C++入門概覽和嘗試創(chuàng)建第一個(gè)C++程序,同時(shí)也包括編寫類的示例展示C++面向?qū)ο蟮奶匦?需要的朋友可以參考下2015-09-09C語言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++11顯示類型轉(zhuǎn)換的優(yōu)點(diǎn)
這篇文章主要介紹了C++11顯示類型轉(zhuǎn)換的優(yōu)點(diǎn),幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下2020-08-08