常用数学函数
计算给定数加1的自然对数(底为e)(ln(1+x))
定义于头文件 | ||
float log1pf( float arg ); | (1) | (C99 起) |
double log1p( double arg ); | (2) | (C99 起) |
long double log1pl( long double arg ); | (3) | (C99 起) |
定义于头文件 | ||
#define log1p( arg ) | (4) | (C99 起) |
1-3) 计算 1+arg 的自然(底 e )对数。若 arg
接近零,则此函数比表达式 log(1+arg) 更精确。
4) 泛型宏:若 arg
拥有 long double 类型,则调用 log1pl
。否则,若 arg
拥有整数类型或 double 类型,则调用 log1p
。否则调用 log1pf
。
参数
arg | - | 浮点值 |
返回值
若不出现错误则返回 ln(1+arg) 。
若出现定义域错误,则返回实现定义值(受支持平台上为 NaN )。
若出现极点错误,则返回 -HUGE_VAL
、 -HUGE_VALF
或 -HUGE_VALL
。
若出现下溢所致的值域错误,则返回(舍入后的)正确结果。
错误处理
报告 math_errhandling 中指定的错误。
若 arg
小于 -1 则出现定义域错误。
若 arg
为 -1 则可能出现极点错误。
若实现支持 IEEE 浮点算术( IEC 60559 ),则
- 若参数为 ±0 ,则返回不修改的参数。
- 若参数为 -1 ,则返回 -∞ 并引发 FE_DIVBYZERO 。
- 若参数小于 -1 ,则返回 NaN 并引发 FE_INVALID 。
- 若参数为 +∞ ,则返回 +∞ 。
- 若参数为 NaN ,则返回 NaN 。
注意
函数 expm1
和 log1p 对于金融计算有用:例如在计算小的日利率时: (1+x)n
-1 能表示为 expm1(n * log1p(x)) 。这些函数亦简化书写精确的反双曲函数。
调用示例
#include <iostream>
#include <cstdlib>
#include <typeinfo>
#include <cinttypes>
#include <cmath>
int main()
{
//计算浮点值 arg 的绝对值。
const float fNumber = 0.1314;
std::cout << "typeid(float).name(): " << typeid(float).name() << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << fNumber + i << "): "
<< std::log1p(fNumber + i) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << -fNumber - i << "): "
<< std::log1p(-fNumber - i) << std::endl;
}
std::cout << std::endl;
const double dNumber = 0.01314;
std::cout << "typeid(double).name(): " << typeid(double).name() << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << dNumber + i << "): "
<< std::log1p(dNumber + i) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << -dNumber - i << "): "
<< std::log1p(-dNumber - i) << std::endl;
}
std::cout << std::endl;
const long double ldNumber = 0.001314;
std::cout << "typeid(long double).name(): " << typeid(long double).name() << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << ldNumber + i << "): "
<< std::log1p(ldNumber + i) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < 1000; i += 100)
{
std::cout << "std::log1p(" << -ldNumber - i << "): "
<< std::log1p(-ldNumber - i) << std::endl;
}
std::cout << std::endl;
return 0;
}
输出
typeid(float).name(): f
std::log1p(0.1314): 0.123456
std::log1p(100.131): 4.61642
std::log1p(200.131): 5.30396
std::log1p(300.131): 5.70755
std::log1p(400.131): 5.99429
std::log1p(500.131): 6.21687
std::log1p(600.131): 6.39881
std::log1p(700.131): 6.5527
std::log1p(800.131): 6.68603
std::log1p(900.131): 6.80365
std::log1p(-0.1314): -0.140873
std::log1p(-100.131): nan
std::log1p(-200.131): nan
std::log1p(-300.131): nan
std::log1p(-400.131): nan
std::log1p(-500.131): nan
std::log1p(-600.131): nan
std::log1p(-700.131): nan
std::log1p(-800.131): nan
std::log1p(-900.131): nan
typeid(double).name(): d
std::log1p(0.01314): 0.0130544
std::log1p(100.013): 4.61525
std::log1p(200.013): 5.30337
std::log1p(300.013): 5.70715
std::log1p(400.013): 5.99399
std::log1p(500.013): 6.21663
std::log1p(600.013): 6.39862
std::log1p(700.013): 6.55253
std::log1p(800.013): 6.68588
std::log1p(900.013): 6.80352
std::log1p(-0.01314): -0.0132271
std::log1p(-100.013): nan
std::log1p(-200.013): nan
std::log1p(-300.013): nan
std::log1p(-400.013): nan
std::log1p(-500.013): nan
std::log1p(-600.013): nan
std::log1p(-700.013): nan
std::log1p(-800.013): nan
std::log1p(-900.013): nan
typeid(long double).name(): e
std::log1p(0.001314): 0.00131314
std::log1p(100.001): 4.61513
std::log1p(200.001): 5.30331
std::log1p(300.001): 5.70711
std::log1p(400.001): 5.99396
std::log1p(500.001): 6.21661
std::log1p(600.001): 6.3986
std::log1p(700.001): 6.55251
std::log1p(800.001): 6.68586
std::log1p(900.001): 6.80351
std::log1p(-0.001314): -0.00131486
std::log1p(-100.001): nan
std::log1p(-200.001): nan
std::log1p(-300.001): nan
std::log1p(-400.001): nan
std::log1p(-500.001): nan
std::log1p(-600.001): nan
std::log1p(-700.001): nan
std::log1p(-800.001): nan
std::log1p(-900.001): nan