跳轉到內容

C 程式設計/高等數學

來自 Wikibooks,開放世界中的開放書籍
上一頁: 字串 C 程式設計 下一頁: 庫

<math.h> 標頭檔案包含處理數學的幾個函式的原型。在 1990 年的 ISO 標準中,只指定了函式的 double 版本;1999 年的版本添加了 floatlong double 版本。要使用這些數學函式,您必須將程式與數學庫連結。對於一些編譯器(包括 GCC),您必須指定額外的引數 -lm[1][2]

數學函式可能會產生兩種錯誤。域錯誤發生在函式引數無效時,例如,將負數作為引數傳遞給sqrt(平方根函式)。範圍錯誤發生在函式結果無法用特定浮點型別表示時,例如pow(1000.0, 1000.0)如果 double 的最大值約為 10308

這些函式可以分為以下幾類

三角函式

[編輯 | 編輯原始碼]

acos 和 asin 函式

[編輯 | 編輯原始碼]

acos 函式返回其引數的反餘弦值(以弧度為單位),asin 函式返回其引數的反正弦值(以弧度為單位)。所有函式都期望引數在 [-1,+1] 範圍內。反餘弦返回 [0,π] 範圍內的值;反正弦返回 [-π/2,+π/2] 範圍內的值。

 #include <math.h>
 float asinf(float x); /* C99 */
 float acosf(float x); /* C99 */
 double asin(double x);
 double acos(double x);
 long double asinl(long double x); /* C99 */
 long double acosl(long double x); /* C99 */

atan 和 atan2 函式

[編輯 | 編輯原始碼]

atan 函式返回其引數的反正切值(以弧度為單位),atan2 函式返回 y/x 的反正切值(以弧度為單位)。atan 函式返回 [-π/2,+π/2] 範圍內的值(±π/2 包含在範圍內的原因是,浮點值可以表示無窮大,而 atan(±∞) = ±π/2);atan2 函式返回 [-π,+π] 範圍內的值。對於 atan2,如果兩個引數都為零,則可能會發生域錯誤。

 #include <math.h>
 float atanf(float x); /* C99 */
 float atan2f(float y, float x); /* C99 */
 double atan(double x);
 double atan2(double y, double x);
 long double atanl(long double x); /* C99 */
 long double atan2l(long double y, long double x); /* C99 */

cos、sin 和 tan 函式

[編輯 | 編輯原始碼]

cos、sin 和 tan 函式分別返回引數的餘弦、正弦和正切值,以弧度表示。

 #include <math.h>
 float cosf(float x); /* C99 */
 float sinf(float x); /* C99 */
 float tanf(float x); /* C99 */
 double cos(double x);
 double sin(double x);
 double tan(double x);
 long double cosl(long double x); /* C99 */
 long double sinl(long double x); /* C99 */
 long double tanl(long double x); /* C99 */

雙曲函式

[編輯 | 編輯原始碼]

cosh, sinhtanh函式分別計算引數的雙曲餘弦、雙曲正弦和雙曲正切。對於雙曲正弦和餘弦函式,如果引數的大小太大,則會發生範圍錯誤。

acosh函式計算引數的反雙曲餘弦。對於小於 1 的引數,會發生域錯誤。

asinh函式計算引數的反雙曲正弦。

atanh函式計算引數的反雙曲正切。如果引數不在 [-1, +1] 區間內,則會發生域錯誤。如果引數等於 -1 或 +1,則可能發生範圍錯誤。

 #include <math.h>
 float coshf(float x); /* C99 */
 float sinhf(float x); /* C99 */
 float tanhf(float x); /* C99 */
 double cosh(double x); 
 double sinh(double x);
 double tanh(double x);
 long double coshl(long double x); /* C99 */
 long double sinhl(long double x); /* C99 */
 long double tanhl(long double x); /* C99 */
 float acoshf(float x); /* C99 */
 float asinhf(float x); /* C99 */
 float atanhf(float x); /* C99 */
 double acosh(double x); /* C99 */
 double asinh(double x); /* C99 */
 double atanh(double x); /* C99 */
 long double acoshl(long double x); /* C99 */
 long double asinhl(long double x); /* C99 */
 long double atanhl(long double x); /* C99 */

指數和對數函式

[編輯 | 編輯原始碼]

exp、exp2 和 expm1 函式

[編輯 | 編輯原始碼]

exp 函式計算 x 的以 e 為底的指數函式 (ex)。如果 x 的大小太大,則會發生範圍錯誤。

exp2 函式計算 x 的以 2 為底的指數函式 (2x)。如果 x 的大小太大,則會發生範圍錯誤。

expm1 函式計算引數的以 e 為底的指數函式,減去 1。如果 x 的大小太大,則會發生範圍錯誤。

 #include <math.h>
 float expf(float x); /* C99 */
 double exp(double x);
 long double expl(long double x); /* C99 */
 float exp2f(float x); /* C99 */
 double exp2(double x); /* C99 */
 long double exp2l(long double x); /* C99 */
 float expm1f(float x); /* C99 */
 double expm1(double x); /* C99 */
 long double expm1l(long double x); /* C99 */

frexp、ldexp、modf、scalbn 和 scalbln 函式

[編輯 | 編輯原始碼]

這些函式在軟體浮點模擬器中被大量使用,但在其他情況下很少被直接呼叫。

在計算機內部,每個浮點數都由兩個部分表示

  • 尾數要麼在 [1/2, 1) 範圍內,要麼等於零。
  • 指數是一個整數。

浮點數 的值是 .

frexp 函式將引數浮點數 value 分解為這兩個部分:指數和尾數。分解後,它將指數儲存在 ex 指向的 int 物件中,並返回尾數。換句話說,返回的值是給定浮點數的副本,但指數被替換為 0。如果 value 為零,則結果的兩個部分均為零。

ldexp 函式將浮點數乘以 2 的整數次冪,並返回結果。換句話說,它返回給定浮點數的副本,其指數增加了 ex。可能會發生範圍錯誤。

modf 函式將引數 value 分解為整數部分和小數部分,它們都與引數具有相同的符號。它們將整數部分儲存在 *iptr 指向的物件中,並返回小數部分。*iptr 是浮點型別,而不是 "int" 型別,因為它可能用於儲存像 1 000 000 000 000 000 000 000 這樣的整數,而這個整數太大,無法放入 int 中。

scalbnscalbln 計算 x × FLT_RADIXnFLT_RADIX 是浮點系統的基數;如果它是 2,則這些函式等效於 ldexp

 #include <math.h>
 float frexpf(float value, int *ex); /* C99 */
 double frexp(double value, int *ex);
 long double frexpl(long double value, int *ex); /* C99 */
 float ldexpf(float x, int ex); /* C99 */
 double ldexp(double x, int ex);
 long double ldexpl(long double x, int ex); /* C99 */
 float modff(float value, float *iptr); /* C99 */
 double modf(double value, double *iptr); 
 long double modfl(long double value, long double *iptr); /* C99 */
 float scalbnf(float x, int ex); /* C99 */
 double scalbn(double x, int ex); /* C99 */
 long double scalbnl(long double x, int ex); /* C99 */
 float scalblnf(float x, long int ex); /* C99 */
 double scalbln(double x, long int ex); /* C99 */
 long double scalblnl(long double x, long int ex); /* C99 */

大多數 C 浮點庫還實現了 IEEE754 推薦的 nextafter()、nextUp() 和 nextDown() 函式。 [3]

loglog2log1plog10 函式

[edit | edit source]

log 函式計算引數的以 e 為底的自然對數,並返回結果。如果引數為負數,則會發生域錯誤。如果引數為零,則可能會發生範圍錯誤。

log1p 函式計算引數加 1 的以 e 為底的自然對數,並返回結果。如果引數小於 -1,則會發生域錯誤。如果引數為 -1,則可能會發生範圍錯誤。

log10 函式計算引數的以 10 為底的常用對數,並返回結果。如果引數為負數,則會發生域錯誤。如果引數為零,則可能會發生範圍錯誤。

log2 函式計算引數的以 2 為底的對數,並返回結果。如果引數為負數,則會發生域錯誤。如果引數為零,則可能會發生範圍錯誤。

 #include <math.h>
 float logf(float x); /* C99 */
 double log(double x);
 long double logl(long double x); /* C99 */
 float log1pf(float x); /* C99 */
 double log1p(double x); /* C99 */
 long double log1pl(long double x); /* C99 */
 float log10f(float x); /* C99 */
 double log10(double x);
 long double log10l(long double x); /* C99 */
 float log2f(float x); /* C99 */
 double log2(double x); /* C99 */
 long double log2l(long double x); /* C99 */

ilogblogb 函式

[edit | edit source]

ilogb 函式將 x 的指數提取為帶符號的 int 值。如果 x 為零,則它們返回 FP_ILOGB0 值;如果 x 為無窮大,則它們返回 INT_MAX 值;如果 x 為 NaN,則它們返回 FP_ILOGBNAN 值;否則,它們等效於呼叫相應的 logb 函式並將返回的值強制轉換為 int 型別。如果 x 為零,則可能會發生範圍錯誤。FP_ILOGB0FP_ILOGBNAN 是在 math.h 中定義的宏;INT_MAX 是在 limits.h 中定義的宏。

logb 函式將 x 的指數提取為浮點格式的帶符號整數。如果 x 為非規格化數,則將其視為規格化數;因此,對於正有限的 x,1 ≤ x × FLT_RADIX-logb(x) < FLT_RADIXFLT_RADIX 是浮點數的基數,在 float.h 標頭檔案中定義。

 #include <math.h>
 int ilogbf(float x); /* C99 */
 int ilogb(double x); /* C99 */
 int ilogbl(long double x); /* C99 */
 float logbf(float x); /* C99 */
 double logb(double x); /* C99 */
 long double logbl(long double x); /* C99 */

冪函式

[edit | edit source]

pow 函式

[edit | edit source]

pow 函式計算 xy 次冪,並返回結果。如果 x 為負數且 y 不是整數值,則會發生域錯誤。如果 x 為零且 y 小於或等於零,則結果無法表示,也會發生域錯誤。可能會發生範圍錯誤。

 #include <math.h>
 float powf(float x, float y); /* C99 */
 double pow(double x, double y);
 long double powl(long double x, long double y); /* C99 */

sqrt 函式

[edit | edit source]

sqrt 函式計算 x 的正平方根,並返回結果。如果引數為負數,則會發生域錯誤。

 #include <math.h>
 float sqrtf(float x); /* C99 */
 double sqrt(double x);
 long double sqrtl(long double x); /* C99 */

cbrt 函式

[edit | edit source]

cbrt 函式計算 x 的立方根,並返回結果。

 #include <math.h>
 float cbrtf(float x); /* C99 */
 double cbrt(double x); /* C99 */
 long double cbrtl(long double x); /* C99 */

hypot 函式

[edit | edit source]

hypot 函式計算 xy 的平方和的平方根,避免溢位或下溢,並返回結果。

 #include <math.h>
 float hypotf(float x, float y); /* C99 */
 double hypot(double x, double y); /* C99 */
 long double hypotl(long double x, long double y); /* C99 */

最接近的整數、絕對值和餘數函式

[edit | edit source]

ceilfloor 函式

[edit | edit source]

ceil 函式計算不小於 x 的最小整數值,並返回結果;floor 函式計算不大於 x 的最大整數值,並返回結果。

 #include <math.h>
 float ceilf(float x); /* C99 */
 double ceil(double x);
 long double ceill(long double x); /* C99 */
 float floorf(float x); /* C99 */
 double floor(double x);
 long double floorl(long double x); /* C99 */

fabs 函式

[edit | edit source]

fabs 函式計算浮點數 x 的絕對值,並返回結果。

 #include <math.h>
 float fabsf(float x); /* C99 */
 double fabs(double x); 
 long double fabsl(long double x); /* C99 */

fmod 函式

[edit | edit source]

fmod 函式計算 x/y 的浮點餘數,並返回 x - i * y 的值,其中 i 是某個整數,使得如果 y 不為零,則結果與 x 具有相同的符號,並且大小小於 y 的大小。如果 y 為零,則是否發生域錯誤或 fmod 函式返回零是實現定義的。

 #include <math.h>
 float fmodf(float x, float y); /* C99 */
 double fmod(double x, double y);
 long double fmodl(long double x, long double y); /* C99 */

nearbyintrintlrintllrint 函式

[編輯 | 編輯原始碼]

nearbyint 函式將它們的實參四捨五入到浮點格式的整數值,使用當前的舍入方向,並且不會引發“不精確”浮點異常。

rint 函式類似於 nearbyint 函式,但如果結果與實參的值不同,它們可能會引發“不精確”浮點異常。

lrintllrint 函式根據當前的舍入方向將它們的實參四捨五入到最接近的整數值。如果結果超出返回型別的值範圍,則數值結果未定義,如果實參的大小過大,則可能會發生範圍錯誤。

 #include <math.h>
 float nearbyintf(float x); /* C99 */
 double nearbyint(double x); /* C99 */
 long double nearbyintl(long double x); /* C99 */
 float rintf(float x); /* C99 */
 double rint(double x); /* C99 */
 long double rintl(long double x); /* C99 */
 long int lrintf(float x); /* C99 */
 long int lrint(double x); /* C99 */
 long int lrintl(long double x); /* C99 */
 long long int llrintf(float x); /* C99 */
 long long int llrint(double x); /* C99 */
 long long int llrintl(long double x); /* C99 */

roundlroundllround 函式

[編輯 | 編輯原始碼]

round 函式將實參四捨五入到浮點格式的最接近的整數值,無論當前的舍入方向如何,都將半途而廢的情況四捨五入到遠離零的方向。

lroundllround 函式將實參四捨五入到最接近的整數值,無論當前的舍入方向如何,都將半途而廢的情況四捨五入到遠離零的方向。如果結果超出返回型別的值範圍,則數值結果未定義,如果實參的大小過大,則可能會發生範圍錯誤。

 #include <math.h>
 float roundf(float x); /* C99 */
 double round(double x); /* C99 */
 long double roundl(long double x); /* C99 */
 long int lroundf(float x); /* C99 */
 long int lround(double x); /* C99 */
 long int lroundl(long double x); /* C99 */
 long long int llroundf(float x); /* C99 */
 long long int llround(double x); /* C99 */
 long long int llroundl(long double x); /* C99 */

trunc 函式

[編輯 | 編輯原始碼]

trunc 函式將它們的實參四捨五入到浮點格式的整數值,該整數值最接近實參,但大小不超過實參。

 #include <math.h>
 float truncf(float x); /* C99 */
 double trunc(double x); /* C99 */
 long double truncl(long double x); /* C99 */

remainder 函式

[編輯 | 編輯原始碼]

remainder 函式計算由 IEC 60559 定義的餘數 x REM y。定義如下:“當 y ≠ 0 時,餘數 r = x REM y 的定義與舍入模式無關,由數學歸納法 r = x - ny 定義,其中 n 是最接近 x/y 的精確值的整數;當 |n - x/y| = ½ 時,則 n 為偶數。因此,餘數總是精確的。如果 r = 0,則它的符號應與 x 的符號相同。”此定義適用於所有實現。

 #include <math.h>
 float remainderf(float x, float y); /* C99 */
 double remainder(double x, double y); /* C99 */
 long double remainderl(long double x, long double y); /* C99 */

remquo 函式

[編輯 | 編輯原始碼]

remquo 函式返回與 remainder 函式相同的餘數。在由 quo 指向的物件中,它們儲存一個值,該值的符號是 x/y 的符號,並且該值的幅度對 2n 取模與 x/y 的整數商的幅度一致,其中 n 是大於或等於 3 的實現定義的整數。

 #include <math.h>
 float remquof(float x, float y, int *quo); /* C99 */
 double remquo(double x, double y, int *quo); /* C99 */
 long double remquol(long double x, long double y, int *quo); /* C99 */

誤差函式和伽馬函式

[編輯 | 編輯原始碼]

erf 函式計算實參 的誤差函式。

erfc 函式計算實參的補誤差函式(即 1 - erf x)。對於 erfc 函式,如果實參過大,則可能會發生範圍錯誤。

lgamma 函式計算實參的伽馬函式的絕對值的自然對數(即 loge|Γ(x)|)。如果實參為負整數或零,則可能會發生範圍錯誤。

tgamma 函式計算實參的伽馬函式(即 Γ(x))。如果實參為負整數,或者如果實參為零時結果無法表示,則會發生域錯誤。可能會發生範圍錯誤。

 #include <math.h>
 float erff(float x); /* C99 */
 double erf(double x); /* C99 */
 long double erfl(long double x); /* C99 */
 float erfcf(float x); /* C99 */
 double erfc(double x); /* C99 */
 long double erfcl(long double x); /* C99 */
 float lgammaf(float x); /* C99 */
 double lgamma(double x); /* C99 */
 long double lgammal(long double x); /* C99 */
 float tgammaf(float x); /* C99 */
 double tgamma(double x); /* C99 */
 long double tgammal(long double x); /* C99 */

參考資料

[編輯 | 編輯原始碼]
  1. [1] 為什麼必須在 C 中連結數學庫?


上一頁: 字串 C 程式設計 下一頁: 庫
華夏公益教科書