iOS 常用数学函数

iOS开发中,常用的c函数,在math.h中

绝对值函数

1. 取绝对值函数:y = |x| fabs()

extern float fabsf(float);
extern double fabs(double);
extern long double fabsl(long double);

取整函数

1. 对x进行向上取整 -- ceil()

extern float ceilf(float x);
extern double ceil(double x);
extern long double ceill(long double x);

2. 对x进行向下取整 -- floor()

extern float floorf(float x);
extern double floor(double x);
extern long double floorl(long double x);

3. 返回一个最接近x的整数 -- rint()

extern float nearbyintf(float x);
extern double nearbyint(double x);
extern long double nearbyintl(long double x);

extern float rintf(float x);
extern double rint(double x);
extern long double rintl(long double x);

extern long int lrintf(float x);
extern long int lrint(double x);
extern long int lrintl(long double x);

4. 对x进行四舍五入取整 -- round()

extern float roundf(float x);
extern double round(double x);
extern long double roundl(long double x);
extern long int lroundf(float x);
extern long int lround(double x);
extern long int lroundl(long double x);

如果我们要实现保留N位小数的四舍五入时。我们可以用如下的方法实现:

double y = round(x * pow(10, N)) / pow(10, N)

PS: ceil()、floor()、rint()、round()比较

ceil()
double z = ceil(-1.1);  //-1
double z = ceil(0.1); // 1
double z = ceil(1.1); // 2

floor()
double z2 = floor(-1.1);  //-2
double z2 = floor(0.1); // 0
double z2 = floor(1.1); // 1

rint()  //如果有2个数同样接近,则会返回偶数的那个
double z3 = rint(-1.1);  //-1
double z3 = rint(-1.5);  //-2
double z3 = rint(-1.6);  //-2

double z3 = rint(0.1); // 0
double z3 = rint(0.5); // 0  0为偶数
double z3 = rint(0.6); // 1

double z3 = rint(1.1); // 1
double z3 = rint(1.5); // 2
double z3 = rint(1.6); // 2

round() //不考虑正负
double z4 = round(-1.1);  //-1
double z4 = round(-1.5);  //-2
double z4 = round(-1.6);  //-2

double z4 = round(0.1); // 0
double z4 = round(0.5); // 1
double z4 = round(0.6); // 1

double z4 = round(1.1); // 1
double z4 = round(1.5); // 2
double z4 = round(1.6); // 2

比较函数

1. 如果x>y,返回x减去y的差,否则返回0 不会出现负数 -- fdim(x,y)

extern float fdimf(float x, float y);
extern double fdim(double x, double y);
extern long double fdiml(long double x, long double y);

2. z = max(x,y) 求最大值 -- fmax(x,y)

extern float fmaxf(float x, float x);
extern double fmax(double x, double x);
extern long double fmaxl(long double x, long double x);

3. z = min(x,y) 求最小值 -- fmin(x,y)

extern float fminf(float x, float y);
extern double fmin(double x, double y);
extern long double fminl(long double x, long double y);

幂函数

1. 平方根函数:y = √x -- sqrt()

extern float sqrtf(float x);
extern double sqrt(double x);
extern long double sqrtl(long double x);

2. 立方根函数: y = ³√x -- cbrt()

extern float cbrtf(float x);
extern double cbrt(double x);
extern long double cbrtl(long double x);

3. 幂函数:z = x ^ y -- pow(x,y)

extern float powf(float x, float y);
extern double pow(double x, double y);
extern long double powl(long double x, long double y);

4. d =√x^2 + y^2 求直角三角形斜边的长度 -- hypot(x,y)

extern float hypotf(float x, float y);
extern double hypot(double x, double y);
extern long double hypotl(long double x, long double y);

数字拆分

1. 返回浮点数x的整数部分 -- trunc()

extern float truncf(float x);
extern double trunc(double x);
extern long double truncl(long double x);

如果我们要实现保留N位小数的截取时。我们可以用如下的方法实现:

double y = trunc(x * pow(10, N)) / pow(10, N)

2. 返回x/y的余数1: z = mod(x, y) -- fmod(x,y)

extern float fmodf(float x, float y);
extern double fmod(double x, double y);
extern long double fmodl(long double x, long double y);

函数返回余数r = x - n*y, 其中n等于x/y的值截取的整数。

3. 返回x/y的余数2: z = mod(x, y) -- remainder(x,y)

extern float remainderf(float x, float y);
extern double remainder(double x, double y);
extern long double remainderl(long double x, long double y);

函数返回余数r = x - n*y, 其中n等于x/y的值取最接近的整数,如果有两个数都接近x/y,那么n就取偶数。

// 7/(2.5) = 2.8
double z = fmod(7, 2.5); 2.8 取 2 - >  7 - 2.5 * 2 = 2
double x = remainder(7, 2.5); // 2.8 取 3 -- >  7 - 2.5 * 3 = -0.5

从上面的描述可以看出fmod和remainder的区别主要在于x/y的整数部分的处理不一样:fmod函数是取x/y的整数来算余数,而remainder函数则取最接近x/y的整数来算余数。

4. 返回x/y的余数和整数商 -- remquo(x,y,&quo)

extern float remquof(float x, float y , int *quo);
extern double remquo(double x, double y, int *quo);
extern long double remquol(long double x, long double y, int * quo);

这个函数和 remainder函数一样,只不过会将整数商也返回给quo,也就是说r = x - n *y这个等式中,r作为函数的返回,而n则返回给quo。

5. 分解出x的整数和小数部分 -- modf(x,&p)

extern float modff(float x, float p*);
extern double modf(double x, double p*);
extern long double modfl(long double x, long double p*);

函数返回小数部分,整数部分存储在p中。

6. 分解出x的指数和尾数部分 -- frexp(x,&p)

extern float frexpf(float x, int * p);
extern double frexp(double x, int * p);
extern long double frexpl(long double x, int * p);

函数返回尾数*符号部分,指数部分存储在p中。需要明确的是如果浮点数x为0或者非规格化浮点数时按浮点数的定义格式返回尾数和指数,而当x为规格化浮点数那么返回的值的区间是[0.5, 1)。这里的返回值和指数值p和上面介绍的规格化浮点数格式: 符号 * (1.尾数) * 2^指数 有差异。因为按照定义返回的尾数部分应该是1.xxx,但是这里的返回值却是[0.5, 1)。其实这并不矛盾,只是函数对返回的值做了特殊处理:因为一个正浮点数可以表示为:1.m * 2^e ==> (2^0 + 0.m) * 2^e ==> (2^0 / 2 + 0.m / 2) *2^(e+1) =>(0.5 + 0.m/2) *2^(e+1)。因此frexp函数返回的真实值是: 尾数除以2,而p存储的是:指数+1
下面函数使用的一些例子:

int p1 = 0;  double y1 = frexp(16.0, &p); //y1=0.5, p= 5
int p2 = 0;  double y2 = frexp(1.0, &p); //y2=0.5, p = 1
int p3 = 0;  double y3 = frexp(0.0, &p); //y3=0, p = 0

这个函数和上面的ldexp函数为互逆函数


三角函数

1. 反余弦函数: y = arccos(x)

extern float acosf(float x);
extern double acos(double x);
extern long double acosl(long double x);

2. 反正弦函数:y = arcsin(x)

extern float asinf(float x);
extern double asin(double x);
extern long double asinl(long double x);

3. 反正切函数: y = arctan(x)

extern float atanf(float x);
extern double atan(double x);
extern long double atanl(long double x);

4. 2个参数的反正切函数:z = arctan(y/x)

extern float atan2f(float y, float x);
extern double atan2(double y, double x);
extern long double atan2l(long double y, long double x);

因为arctan的定义域是在(-∞, +∞),而值域是在(-????/2, ????/2)之间。因此 :

atan2f(-1.0, 0.0) == -????/2;  atan2f(1.0, 0.0) == ????/2;

这个函数提供的另外一个意义在于tan函数的值其实就是对边除以邻边的结果,因此当知道对边和邻边时就可以直接用这个逆三角函数来求得对应的弧度值。假如特殊情况下对边和邻边的值都是0.0,那么如果你调用atan(0.0/0.0)得到的值将是NAN而不是0。因为0.0/0.0的值是NAN,而对NAN调用atan函数返回的也是NAN,但是对atan2(0.0,0.0)调用返回的结果就是正确值0。

5. 余弦函数: y = cos(x)

extern float cosf(float x);
extern double cos(double x);
extern long double cosl(long double x);

6. 正弦函数:y = sin(x)

extern float sinf(float x);
extern double sin(double x);
extern long double sinl(long double x);

7. 正切函数:y = tan(x)

extern float tanf(float x);
extern double tan(double x);
extern long double tanl(long double x);

双曲函数

1. 反双曲余弦函数:y = arccosh(x)

extern float acoshf(float x);
extern double acosh(double x);
extern long double acoshl(long double x);

2. 反双曲正弦函数:y = arcsinh(x)

extern float asinhf(float x);
extern double asinh(double x);
extern long double asinhl(long double x);

3. 反双曲正切函数:y = arctanh(x)

extern float atanhf(float x);
extern double atanh(double x);
extern long double atanhl(long double x);

4. 双曲余弦函数:y = cosh(x)

extern float coshf(float x);
extern double cosh(double x);
extern long double coshl(long double x);

5. 双曲正弦函数:y = sinh(x)

extern float sinhf(float x);
extern double sinh(double x);
extern long double sinhl(long double x);

6. 双曲正切函数: y = tanh(x)

extern float tanhf(float x);
extern double tanh(double x);
extern long double tanhl(long double x);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值