GCE-Math(通用常數表達式數學)是一個模板化 C++ 函式庫,支援數學函式的編譯時計算。
特徵:
constexpr
格式編寫,並且相容於 C++11/14/17/20。gcem::
語法與 C++ 標準函式庫 ( std::
) 的語法相同。作者:基斯‧奧哈拉
該庫得到積極維護,並且仍在擴展。功能清單包括:
abs
、 max
、 min
、 pow
、 sqrt
、 inv_sqrt
、ceil
, floor
, round
, trunc
, fmod
,exp
、 expm1
、 log
、 log1p
、 log2
、 log10
等cos
、 sin
、 tan
acos
、 asin
、 atan
、 atan2
cosh
、 sinh
、 tanh
、 acosh
、 asinh
、 atanh
lcm
gcd
factorial
, binomial_coef
beta
、 lbeta
、 lgamma
、 tgamma
、 lmgamma
erf
、 erf_inv
incomplete_beta
、 incomplete_gamma
incomplete_beta_inv
、 incomplete_gamma_inv
完整文件可線上取得:
此處提供了該文件的 PDF 版本。
GCE-Math 是一個僅包含頭檔的函式庫,不需要任何其他函式庫或實用程式(除了 C++11 相容編譯器之外)。只需使用以下方法將頭檔新增至您的專案:
# include " gcem.hpp "
您可以使用 Conda 套件管理器安裝 GCE-Math。
conda install -c conda-forge gcem
您也可以使用 CMake 從來源安裝該程式庫。
# clone gcem from GitHub
git clone https://github.com/kthohr/gcem ./gcem
# make a build directory
cd ./gcem
mkdir build
cd build
# generate Makefiles and install
cmake .. -DCMAKE_INSTALL_PREFIX=/gcem/install/location
make install
例如, /gcem/install/location
可以是/usr/local/
。
有兩種建立測試套件的方法。在類似 Unix 的系統上,Makefile 在tests/
下可用。
cd ./gcem/tests
make
./run_tests
使用 CMake,選項GCEM_BUILD_TESTS=1
產生建置測試套件所需的 Makefile。
cd ./gcem
mkdir build
cd build
cmake ../ -DGCEM_BUILD_TESTS=1 -DCMAKE_INSTALL_PREFIX=/gcem/install/location
make gcem_tests
cd tests
./exp.test
您可以使用互動式 Jupyter 筆記本在線測試該程式庫:
GCE-Math 函數被編寫為帶有constexpr
說明符的 C++ 模板,其格式可能會讓不熟悉基於模板的程式設計的使用者感到困惑。
例如,高斯誤差函數 ( erf
) 定義為:
template < typename T>
constexpr
return_t <T>
erf ( const T x) noexcept ;
一組內部模板化constexpr
函數將實作連分式擴充並傳回return_t<T>
類型的值。輸出型別(' return_t<T>
')一般由輸入型別決定,例如int
、 float
、 double
、 long double
等;當T
是整數時,輸出會升級為return_t<T> = double
,否則return_t<T> = T
。對於std::is_integral
未涵蓋的類型,應使用重鑄。
計算 10!:
# include " gcem.hpp "
int main ()
{
constexpr int x = 10 ;
constexpr int res = gcem::factorial (x);
return 0 ;
}
檢查 Clang 7.0.0 產生的彙編程式碼:
push rbp
mov rbp , rsp
xor eax , eax
mov dword ptr [ rbp - 4 ], 0
mov dword ptr [ rbp - 8 ], 10
mov dword ptr [ rbp - 12 ], 3628800
pop rbp
ret
我們看到函數呼叫已被數值取代(10!= 3628800)。
類似地,計算某一點的 log Gamma 函數:
# include " gcem.hpp "
int main ()
{
constexpr long double x = 1.5 ;
constexpr long double res = gcem::lgamma (x);
return 0 ;
}
彙編程式碼:
.LCPI0_0:
.long 1069547520 # float 1 . 5
.LCPI0_1:
.quad - 622431863250842976 # x86_fp80 - 0 . 120782237635245222719
.short 49147
.zero 6
main: # @main
push rbp
mov rbp , rsp
xor eax , eax
mov dword ptr [ rbp - 4 ], 0
fld dword ptr [ rip + .LCPI0_0 ]
fstp tbyte ptr [ rbp - 32 ]
fld tbyte ptr [ rip + .LCPI0_1 ]
fstp tbyte ptr [ rbp - 48 ]
pop rbp
ret