Skip to content

Commit 8fc5716

Browse files
ZERICO2005adriweb
authored andcommitted
Improved/formatted the hyperbolic and inverse trig functions
1 parent b1eaf9b commit 8fc5716

File tree

12 files changed

+312
-132
lines changed

12 files changed

+312
-132
lines changed

src/libc/acoshf.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#include <math.h>
22

3-
float acoshf(float x)
4-
{
5-
return logf(x + sqrtf(x * x - 1));
3+
/**
4+
* @remarks Minimum ulp:
5+
* ulp of -2 at +0x1.0007e8p+0 with ideal log1pf
6+
* ulp of +10 at +0x1.01c964p+0 with current log1pf
7+
*/
8+
float acoshf(float x) {
9+
if (x < 0x1.0p+63f) {
10+
float t = x - 1.0f;
11+
return log1pf(t + sqrtf(2.0f * t + t * t));
12+
}
13+
return logf(x) + (float)M_LN2;
614
}
715

816
double acosh(double) __attribute__((alias("acoshf")));

src/libc/acoshl.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
#include <math.h>
2+
#include "__float64_constants.h"
23

3-
long double acoshl(long double x)
4-
{
5-
return logl(x + sqrtl(x * x - 1));
4+
/* enable when log1pl is implemented */
5+
#if 0
6+
7+
/**
8+
* @remarks Minimum relative precision of:
9+
* 2^-42.37 at +1.000000358e+00 with ideal log1pl
10+
*/
11+
long double acoshl(long double x) {
12+
if (x < 0x1.0p+511L) {
13+
long double t = x - 1.0L;
14+
return log1pl(t + sqrtl(2.0L * t + t * t));
15+
}
16+
return logl(x) + F64_LN2;
617
}
18+
19+
#else
20+
21+
long double acoshl(long double x) {
22+
if (x < 0x1.0p+511L) {
23+
return logl(x + sqrtl(x * x - 1.0L));
24+
}
25+
return logl(x) + F64_LN2;
26+
}
27+
28+
#endif

src/libc/asinf.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,33 @@
77

88
#include <errno.h>
99
#include <math.h>
10+
#include <stdbool.h>
1011

11-
#define pio2 1.57079632679490
12-
12+
/**
13+
* @remarks Minimum ulp:
14+
* ulp of +8 at +0x1.ffe956p-1
15+
*/
1316
float _asinf_c(float arg) {
14-
float sign, temp;
17+
bool arg_sign;
18+
float temp;
19+
arg_sign = signbit(arg);
20+
arg = fabsf(arg);
1521

16-
sign = 1.;
17-
if(arg < 0) {
18-
arg = -arg;
19-
sign = -1.;
20-
}
21-
22-
if(arg > 1.) {
22+
if(arg > 1.0f) {
2323
errno = EDOM;
24-
return(0.);
24+
return 0.0f;
2525
}
2626

27-
temp = sqrtf(1. - arg*arg);
28-
if(arg > 0.7) {
29-
temp = pio2 - atanf(temp/arg);
27+
temp = sqrtf(1.0f - arg*arg);
28+
if(arg > 0.7f) {
29+
temp = (float)M_PI_2 - atanf(temp/arg);
3030
} else {
3131
temp = atanf(arg/temp);
3232
}
33-
34-
return(sign*temp);
33+
if (arg_sign) {
34+
temp = -temp;
35+
}
36+
return temp;
3537
}
3638

3739
double _asin_c(double) __attribute__((alias("_asinf_c")));

src/libc/asinhf.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
#include <math.h>
2+
#include "__float32_constants.h"
23

3-
float asinhf(float x)
4-
{
5-
return logf(x + sqrtf(x * x + 1));
4+
/**
5+
* @remarks Minimum ulp:
6+
* ulp of -20 at +0x1.ff2afcp-5
7+
*/
8+
float asinhf(float arg) {
9+
float x = fabsf(arg);
10+
if (x < 0.0703125f) {
11+
x = x - (x * x * x) * F32_1_DIV_6;
12+
} else if (x < 0x1.0p+63f) {
13+
x = logf(x + sqrtf(x * x + 1.0f));
14+
} else {
15+
x = logf(x) + F32_LN2;
16+
}
17+
return copysignf(x, arg);
618
}
719

820
double asinh(double) __attribute__((alias("asinhf")));

src/libc/asinhl.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
#include <math.h>
2+
#include "__float64_constants.h"
23

3-
long double asinhl(long double x)
4-
{
5-
return logl(x + sqrtl(x * x + 1));
4+
/**
5+
* @remarks Relative precision of:
6+
* 2^-42.41 at +9.768006857e-04 with ideal logl
7+
*/
8+
long double asinhl(long double arg) {
9+
long double x = fabsl(arg);
10+
if (x < 0x1.0p-10L) {
11+
x = x - (x * x * x) * F64_1_DIV_6;
12+
} else if (x < 0x1.0p+511L) {
13+
x = logl(x + sqrtl(x * x + 1.0L));
14+
} else {
15+
x = logl(x) + F64_LN2;
16+
}
17+
return copysignl(x, arg);
618
}

src/libc/atanhf.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
#include <math.h>
22

3-
float atanhf(float x)
4-
{
5-
return .5f * logf((1 + x) / (1 - x));
3+
/**
4+
* @remarks Minimum ulp:
5+
* ulp of +2 at +0x1.fe2dd0p-9 with ideal log1pf
6+
* ulp of -9 at +0x1.e1e8d0p-5 with current log1pf and ideal logf
7+
* ulp of +11 at +0x1.f30abcp-5 with current log1pf and logf
8+
*/
9+
float atanhf(float arg) {
10+
float x = fabsf(arg);
11+
x = 0.5f * log1pf((2.0f * x) / (1.0f - x));
12+
return copysignf(x, arg);
613
}
714

815
double atanh(double) __attribute__((alias("atanhf")));

src/libc/atanhl.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
#include <math.h>
22

3+
/* enable when log1pl is implemented */
4+
#if 0
5+
6+
/**
7+
* @remarks Relative precision of:
8+
* 2^-51 at +1.277396381e-01 with ideal log1pl
9+
*/
10+
long double atanhl(long double arg) {
11+
long double x = fabsl(arg);
12+
x = 0.5L * log1pl((2.0L * x) / (1.0L - x));
13+
return copysignl(x, arg);
14+
}
15+
16+
#else
17+
318
long double atanhl(long double x)
419
{
5-
return .5L * logl((1 + x) / (1 - x));
20+
return 0.5L * logl((1.0L + x) / (1.0L - x));
621
}
22+
23+
#endif

src/libc/coshf.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,25 @@
2222

2323
#include <math.h>
2424

25-
#define p0 -0.630767364049772e+6
26-
#define p1 -0.899127202203951e+5
27-
#define p2 -0.289421135598956e+4
28-
#define p3 -0.263056321339750e+2
29-
#define q0 -0.630767364049772e+6
30-
#define q1 0.152151737879002e+5
31-
#define q2 -0.173678953558234e+3
32-
25+
/**
26+
* @remarks Minimum ulp:
27+
* ulp of -1 at +0x1.39a3fep-12 with ideal expf (|x| < 21.0f)
28+
* ulp of -18 at +0x1.0a049cp+4 with current expf (|x| < 21.0f)
29+
*/
3330
float _coshf_c(float arg) {
3431
float val;
35-
36-
if(arg < 0) {
37-
arg = -arg;
38-
}
32+
arg = fabsf(arg);
3933

4034
val = expf(arg);
4135

42-
if(arg > 21.) {
43-
return val/2;
36+
if (arg > 21.0f) {
37+
return val / 2.0f;
4438
}
4539

4640
val += expf(-arg);
47-
val /= 2;
41+
val /= 2.0f;
4842
return val;
4943
}
5044

5145
double _cosh_c(double) __attribute__((alias("_coshf_c")));
46+

src/libc/sinhf.c

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,33 @@
2222

2323
#include <math.h>
2424

25-
#define p0 -0.630767364049772e+6
26-
#define p1 -0.899127202203951e+5
27-
#define p2 -0.289421135598956e+4
28-
#define p3 -0.263056321339750e+2
29-
#define q0 -0.630767364049772e+6
30-
#define q1 0.152151737879002e+5
31-
#define q2 -0.173678953558234e+3
32-
25+
#define p0 -0.630767364049772e+6f
26+
#define p1 -0.899127202203951e+5f
27+
#define p2 -0.289421135598956e+4f
28+
#define p3 -0.263056321339750e+2f
29+
#define q0 -0.630767364049772e+6f
30+
#define q1 0.152151737879002e+5f
31+
#define q2 -0.173678953558234e+3f
32+
33+
/**
34+
* @remarks Minimum ulp:
35+
* ulp of -3 at +0x1.eec25ap-9 with ideal expf (|x| < 21.0f)
36+
* ulp of -18 at +0x1.0a049cp+4 with current expf (|x| < 21.0f)
37+
*/
3338
float _sinhf_c(float arg) {
34-
float temp, argsq;
35-
register int sign;
36-
37-
sign = 1;
38-
if(arg < 0) {
39-
arg = -arg;
40-
sign = -1;
41-
}
42-
43-
if(arg > 21.) {
44-
temp = expf(arg)/2;
45-
if (sign>0)
46-
return(temp);
47-
else
48-
return(-temp);
39+
float temp, argsq, x;
40+
x = fabsf(arg);
41+
42+
if (x > 21.0f) {
43+
temp = expf(x) / 2.0f;
44+
} else if (x > 0.5f) {
45+
temp = (expf(x) - expf(-x)) / 2.0f;
46+
} else {
47+
argsq = x * x;
48+
temp = (((p3*argsq+p2)*argsq+p1)*argsq+p0) * x;
49+
temp /= (((argsq+q2)*argsq+q1)*argsq+q0);
4950
}
50-
51-
if(arg > 0.5) {
52-
return(sign*(expf(arg) - expf(-arg))/2);
53-
}
54-
55-
argsq = arg*arg;
56-
temp = (((p3*argsq+p2)*argsq+p1)*argsq+p0)*arg;
57-
temp /= (((argsq+q2)*argsq+q1)*argsq+q0);
58-
return(sign*temp);
51+
return copysignf(temp, arg);
5952
}
6053

6154
double _sinh_c(double, double *) __attribute__((alias("_sinhf_c")));

0 commit comments

Comments
 (0)