Skip to content

Commit 3b62c65

Browse files
Add lots of math functions.
1 parent 75a6be6 commit 3b62c65

14 files changed

+252
-9
lines changed

emcc

+11
Original file line numberDiff line numberDiff line change
@@ -1542,11 +1542,22 @@ try:
15421542
['math', [
15431543
'__cosdf.c',
15441544
'__sindf.c',
1545+
'ilogb.c',
1546+
'ilogbf.c',
1547+
'ilogbl.c',
1548+
'ldexp.c',
1549+
'ldexpf.c',
1550+
'ldexpl.c',
1551+
'logb.c',
1552+
'logbf.c',
1553+
'logbl.c',
15451554
'lgamma.c',
15461555
'lgamma_r.c',
15471556
'lgammaf.c',
15481557
'lgammaf_r.c',
15491558
'lgammal.c',
1559+
'scalbn.c',
1560+
'scalbnf.c',
15501561
'signgam.c',
15511562
'tgamma.c',
15521563
'tgammaf.c',

src/library.js

-9
Original file line numberDiff line numberDiff line change
@@ -4827,15 +4827,6 @@ LibraryManager.library = {
48274827
llvm_log_f64: 'Math_log',
48284828
llvm_exp_f32: 'Math_exp',
48294829
llvm_exp_f64: 'Math_exp',
4830-
ldexp: function(x, exp_) {
4831-
return x * Math.pow(2, exp_);
4832-
},
4833-
ldexpf: 'ldexp',
4834-
scalb: 'ldexp',
4835-
scalbn: 'ldexp',
4836-
scalbnf: 'ldexp',
4837-
scalbln: 'ldexp',
4838-
scalblnf: 'ldexp',
48394830
cbrt: function(x) {
48404831
return Math.pow(x, 1/3);
48414832
},

system/lib/libc/musl/src/math/ilogb.c

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <limits.h>
2+
#include "libm.h"
3+
4+
int ilogb(double x)
5+
{
6+
#pragma STDC FENV_ACCESS ON
7+
union {double f; uint64_t i;} u = {x};
8+
uint64_t i = u.i;
9+
int e = i>>52 & 0x7ff;
10+
11+
if (!e) {
12+
i <<= 12;
13+
if (i == 0) {
14+
FORCE_EVAL(0/0.0f);
15+
return FP_ILOGB0;
16+
}
17+
/* subnormal x */
18+
for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
19+
return e;
20+
}
21+
if (e == 0x7ff) {
22+
FORCE_EVAL(0/0.0f);
23+
return i<<12 ? FP_ILOGBNAN : INT_MAX;
24+
}
25+
return e - 0x3ff;
26+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <limits.h>
2+
#include "libm.h"
3+
4+
int ilogbf(float x)
5+
{
6+
#pragma STDC FENV_ACCESS ON
7+
union {float f; uint32_t i;} u = {x};
8+
uint32_t i = u.i;
9+
int e = i>>23 & 0xff;
10+
11+
if (!e) {
12+
i <<= 9;
13+
if (i == 0) {
14+
FORCE_EVAL(0/0.0f);
15+
return FP_ILOGB0;
16+
}
17+
/* subnormal x */
18+
for (e = -0x7f; i>>31 == 0; e--, i<<=1);
19+
return e;
20+
}
21+
if (e == 0xff) {
22+
FORCE_EVAL(0/0.0f);
23+
return i<<9 ? FP_ILOGBNAN : INT_MAX;
24+
}
25+
return e - 0x7f;
26+
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <limits.h>
2+
#include "libm.h"
3+
4+
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5+
int ilogbl(long double x)
6+
{
7+
return ilogb(x);
8+
}
9+
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
10+
int ilogbl(long double x)
11+
{
12+
#pragma STDC FENV_ACCESS ON
13+
union ldshape u = {x};
14+
uint64_t m = u.i.m;
15+
int e = u.i.se & 0x7fff;
16+
17+
if (!e) {
18+
if (m == 0) {
19+
FORCE_EVAL(0/0.0f);
20+
return FP_ILOGB0;
21+
}
22+
/* subnormal x */
23+
for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
24+
return e;
25+
}
26+
if (e == 0x7fff) {
27+
FORCE_EVAL(0/0.0f);
28+
return m<<1 ? FP_ILOGBNAN : INT_MAX;
29+
}
30+
return e - 0x3fff;
31+
}
32+
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
33+
int ilogbl(long double x)
34+
{
35+
#pragma STDC FENV_ACCESS ON
36+
union ldshape u = {x};
37+
int e = u.i.se & 0x7fff;
38+
39+
if (!e) {
40+
if (x == 0) {
41+
FORCE_EVAL(0/0.0f);
42+
return FP_ILOGB0;
43+
}
44+
/* subnormal x */
45+
x *= 0x1p120;
46+
return ilogbl(x) - 120;
47+
}
48+
if (e == 0x7fff) {
49+
FORCE_EVAL(0/0.0f);
50+
u.i.se = 0;
51+
return u.f ? FP_ILOGBNAN : INT_MAX;
52+
}
53+
return e - 0x3fff;
54+
}
55+
#endif

system/lib/libc/musl/src/math/ldexp.c

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <math.h>
2+
3+
double ldexp(double x, int n)
4+
{
5+
return scalbn(x, n);
6+
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <math.h>
2+
3+
float ldexpf(float x, int n)
4+
{
5+
return scalbnf(x, n);
6+
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <math.h>
2+
3+
long double ldexpl(long double x, int n)
4+
{
5+
return scalbnl(x, n);
6+
}

system/lib/libc/musl/src/math/logb.c

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <math.h>
2+
3+
/*
4+
special cases:
5+
logb(+-0) = -inf, and raise divbyzero
6+
logb(+-inf) = +inf
7+
logb(nan) = nan
8+
*/
9+
10+
double logb(double x)
11+
{
12+
if (!isfinite(x))
13+
return x * x;
14+
if (x == 0)
15+
return -1/(x*x);
16+
return ilogb(x);
17+
}

system/lib/libc/musl/src/math/logbf.c

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <math.h>
2+
3+
float logbf(float x)
4+
{
5+
if (!isfinite(x))
6+
return x * x;
7+
if (x == 0)
8+
return -1/(x*x);
9+
return ilogbf(x);
10+
}

system/lib/libc/musl/src/math/logbl.c

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <math.h>
2+
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
3+
long double logbl(long double x)
4+
{
5+
return logb(x);
6+
}
7+
#else
8+
long double logbl(long double x)
9+
{
10+
if (!isfinite(x))
11+
return x * x;
12+
if (x == 0)
13+
return -1/(x*x);
14+
return ilogbl(x);
15+
}
16+
#endif
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
double scalbn(double x, int n)
5+
{
6+
union {double f; uint64_t i;} u;
7+
double_t y = x;
8+
9+
if (n > 1023) {
10+
y *= 0x1p1023;
11+
n -= 1023;
12+
if (n > 1023) {
13+
y *= 0x1p1023;
14+
n -= 1023;
15+
if (n > 1023)
16+
n = 1023;
17+
}
18+
} else if (n < -1022) {
19+
y *= 0x1p-1022;
20+
n += 1022;
21+
if (n < -1022) {
22+
y *= 0x1p-1022;
23+
n += 1022;
24+
if (n < -1022)
25+
n = -1022;
26+
}
27+
}
28+
u.i = (uint64_t)(0x3ff+n)<<52;
29+
x = y * u.f;
30+
return x;
31+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
float scalbnf(float x, int n)
5+
{
6+
union {float f; uint32_t i;} u;
7+
float_t y = x;
8+
9+
if (n > 127) {
10+
y *= 0x1p127f;
11+
n -= 127;
12+
if (n > 127) {
13+
y *= 0x1p127f;
14+
n -= 127;
15+
if (n > 127)
16+
n = 127;
17+
}
18+
} else if (n < -126) {
19+
y *= 0x1p-126f;
20+
n += 126;
21+
if (n < -126) {
22+
y *= 0x1p-126f;
23+
n += 126;
24+
if (n < -126)
25+
n = -126;
26+
}
27+
}
28+
u.i = (uint32_t)(0x7f+n)<<23;
29+
x = y * u.f;
30+
return x;
31+
}

system/lib/libcextra.symbols

+11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
T iconv
2525
T iconv_close
2626
T iconv_open
27+
T ilogb
28+
T ilogbf
29+
T ilogbl
2730
T iswalnum
2831
T iswalnum_l
2932
T iswalpha
@@ -50,12 +53,18 @@
5053
T iswupper_l
5154
T iswxdigit
5255
T iswxdigit_l
56+
T ldexp
57+
T ldexpf
58+
T ldexpl
5359
T lgamma
5460
W lgamma_r
5561
T lgammaf
5662
W lgammaf_r
5763
T lgammal
5864
W lgammal_r
65+
T logb
66+
T logbf
67+
T logbl
5968
T mblen
6069
T mbrlen
6170
T mbrtowc
@@ -72,6 +81,8 @@
7281
T regerror
7382
T regexec
7483
T regfree
84+
T scalbn
85+
T scalbnf
7586
D signgam
7687
T strcasecmp_l
7788
T strcasestr

0 commit comments

Comments
 (0)