Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
9ab94c46
Commit
9ab94c46
authored
Feb 22, 2015
by
Damien George
Browse files
lib/libm: Add implementations of erf, erfc, lgamma, tgamma.
parent
35270855
Changes
7
Hide whitespace changes
Inline
Side-by-side
lib/libm/erf_lgamma.c
0 → 100644
View file @
9ab94c46
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* These math functions are taken from newlib-nano-2, the newlib/libm/math
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
*
* Appropriate copyright headers are reproduced below.
*/
/* erf_lgamma.c -- float version of er_lgamma.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
#include
"fdlibm.h"
#define __ieee754_logf logf
#ifdef __STDC__
static
const
float
#else
static
float
#endif
two23
=
8.3886080000e+06
,
/* 0x4b000000 */
half
=
5.0000000000e-01
,
/* 0x3f000000 */
one
=
1.0000000000e+00
,
/* 0x3f800000 */
pi
=
3.1415927410e+00
,
/* 0x40490fdb */
a0
=
7.7215664089e-02
,
/* 0x3d9e233f */
a1
=
3.2246702909e-01
,
/* 0x3ea51a66 */
a2
=
6.7352302372e-02
,
/* 0x3d89f001 */
a3
=
2.0580807701e-02
,
/* 0x3ca89915 */
a4
=
7.3855509982e-03
,
/* 0x3bf2027e */
a5
=
2.8905137442e-03
,
/* 0x3b3d6ec6 */
a6
=
1.1927076848e-03
,
/* 0x3a9c54a1 */
a7
=
5.1006977446e-04
,
/* 0x3a05b634 */
a8
=
2.2086278477e-04
,
/* 0x39679767 */
a9
=
1.0801156895e-04
,
/* 0x38e28445 */
a10
=
2.5214456400e-05
,
/* 0x37d383a2 */
a11
=
4.4864096708e-05
,
/* 0x383c2c75 */
tc
=
1.4616321325e+00
,
/* 0x3fbb16c3 */
tf
=
-
1.2148628384e-01
,
/* 0xbdf8cdcd */
/* tt = -(tail of tf) */
tt
=
6.6971006518e-09
,
/* 0x31e61c52 */
t0
=
4.8383611441e-01
,
/* 0x3ef7b95e */
t1
=
-
1.4758771658e-01
,
/* 0xbe17213c */
t2
=
6.4624942839e-02
,
/* 0x3d845a15 */
t3
=
-
3.2788541168e-02
,
/* 0xbd064d47 */
t4
=
1.7970675603e-02
,
/* 0x3c93373d */
t5
=
-
1.0314224288e-02
,
/* 0xbc28fcfe */
t6
=
6.1005386524e-03
,
/* 0x3bc7e707 */
t7
=
-
3.6845202558e-03
,
/* 0xbb7177fe */
t8
=
2.2596477065e-03
,
/* 0x3b141699 */
t9
=
-
1.4034647029e-03
,
/* 0xbab7f476 */
t10
=
8.8108185446e-04
,
/* 0x3a66f867 */
t11
=
-
5.3859531181e-04
,
/* 0xba0d3085 */
t12
=
3.1563205994e-04
,
/* 0x39a57b6b */
t13
=
-
3.1275415677e-04
,
/* 0xb9a3f927 */
t14
=
3.3552918467e-04
,
/* 0x39afe9f7 */
u0
=
-
7.7215664089e-02
,
/* 0xbd9e233f */
u1
=
6.3282704353e-01
,
/* 0x3f2200f4 */
u2
=
1.4549225569e+00
,
/* 0x3fba3ae7 */
u3
=
9.7771751881e-01
,
/* 0x3f7a4bb2 */
u4
=
2.2896373272e-01
,
/* 0x3e6a7578 */
u5
=
1.3381091878e-02
,
/* 0x3c5b3c5e */
v1
=
2.4559779167e+00
,
/* 0x401d2ebe */
v2
=
2.1284897327e+00
,
/* 0x4008392d */
v3
=
7.6928514242e-01
,
/* 0x3f44efdf */
v4
=
1.0422264785e-01
,
/* 0x3dd572af */
v5
=
3.2170924824e-03
,
/* 0x3b52d5db */
s0
=
-
7.7215664089e-02
,
/* 0xbd9e233f */
s1
=
2.1498242021e-01
,
/* 0x3e5c245a */
s2
=
3.2577878237e-01
,
/* 0x3ea6cc7a */
s3
=
1.4635047317e-01
,
/* 0x3e15dce6 */
s4
=
2.6642270386e-02
,
/* 0x3cda40e4 */
s5
=
1.8402845599e-03
,
/* 0x3af135b4 */
s6
=
3.1947532989e-05
,
/* 0x3805ff67 */
r1
=
1.3920053244e+00
,
/* 0x3fb22d3b */
r2
=
7.2193557024e-01
,
/* 0x3f38d0c5 */
r3
=
1.7193385959e-01
,
/* 0x3e300f6e */
r4
=
1.8645919859e-02
,
/* 0x3c98bf54 */
r5
=
7.7794247773e-04
,
/* 0x3a4beed6 */
r6
=
7.3266842264e-06
,
/* 0x36f5d7bd */
w0
=
4.1893854737e-01
,
/* 0x3ed67f1d */
w1
=
8.3333335817e-02
,
/* 0x3daaaaab */
w2
=
-
2.7777778450e-03
,
/* 0xbb360b61 */
w3
=
7.9365057172e-04
,
/* 0x3a500cfd */
w4
=
-
5.9518753551e-04
,
/* 0xba1c065c */
w5
=
8.3633989561e-04
,
/* 0x3a5b3dd2 */
w6
=
-
1.6309292987e-03
;
/* 0xbad5c4e8 */
#ifdef __STDC__
static
const
float
zero
=
0.0000000000e+00
;
#else
static
float
zero
=
0.0000000000e+00
;
#endif
#ifdef __STDC__
static
float
sin_pif
(
float
x
)
#else
static
float
sin_pif
(
x
)
float
x
;
#endif
{
float
y
,
z
;
__int32_t
n
,
ix
;
GET_FLOAT_WORD
(
ix
,
x
);
ix
&=
0x7fffffff
;
if
(
ix
<
0x3e800000
)
return
__kernel_sinf
(
pi
*
x
,
zero
,
0
);
y
=
-
x
;
/* x is assume negative */
/*
* argument reduction, make sure inexact flag not raised if input
* is an integer
*/
z
=
floorf
(
y
);
if
(
z
!=
y
)
{
/* inexact anyway */
y
*=
(
float
)
0
.
5
;
y
=
(
float
)
2
.
0
*
(
y
-
floorf
(
y
));
/* y = |x| mod 2.0 */
n
=
(
__int32_t
)
(
y
*
(
float
)
4
.
0
);
}
else
{
if
(
ix
>=
0x4b800000
)
{
y
=
zero
;
n
=
0
;
/* y must be even */
}
else
{
if
(
ix
<
0x4b000000
)
z
=
y
+
two23
;
/* exact */
GET_FLOAT_WORD
(
n
,
z
);
n
&=
1
;
y
=
n
;
n
<<=
2
;
}
}
switch
(
n
)
{
case
0
:
y
=
__kernel_sinf
(
pi
*
y
,
zero
,
0
);
break
;
case
1
:
case
2
:
y
=
__kernel_cosf
(
pi
*
((
float
)
0
.
5
-
y
),
zero
);
break
;
case
3
:
case
4
:
y
=
__kernel_sinf
(
pi
*
(
one
-
y
),
zero
,
0
);
break
;
case
5
:
case
6
:
y
=
-
__kernel_cosf
(
pi
*
(
y
-
(
float
)
1
.
5
),
zero
);
break
;
default:
y
=
__kernel_sinf
(
pi
*
(
y
-
(
float
)
2
.
0
),
zero
,
0
);
break
;
}
return
-
y
;
}
#ifdef __STDC__
float
__ieee754_lgammaf_r
(
float
x
,
int
*
signgamp
)
#else
float
__ieee754_lgammaf_r
(
x
,
signgamp
)
float
x
;
int
*
signgamp
;
#endif
{
float
t
,
y
,
z
,
nadj
=
0
.
0
,
p
,
p1
,
p2
,
p3
,
q
,
r
,
w
;
__int32_t
i
,
hx
,
ix
;
GET_FLOAT_WORD
(
hx
,
x
);
/* purge off +-inf, NaN, +-0, and negative arguments */
*
signgamp
=
1
;
ix
=
hx
&
0x7fffffff
;
if
(
ix
>=
0x7f800000
)
return
x
*
x
;
if
(
ix
==
0
)
return
one
/
zero
;
if
(
ix
<
0x1c800000
)
{
/* |x|<2**-70, return -log(|x|) */
if
(
hx
<
0
)
{
*
signgamp
=
-
1
;
return
-
__ieee754_logf
(
-
x
);
}
else
return
-
__ieee754_logf
(
x
);
}
if
(
hx
<
0
)
{
if
(
ix
>=
0x4b000000
)
/* |x|>=2**23, must be -integer */
return
one
/
zero
;
t
=
sin_pif
(
x
);
if
(
t
==
zero
)
return
one
/
zero
;
/* -integer */
nadj
=
__ieee754_logf
(
pi
/
fabsf
(
t
*
x
));
if
(
t
<
zero
)
*
signgamp
=
-
1
;
x
=
-
x
;
}
/* purge off 1 and 2 */
if
(
ix
==
0x3f800000
||
ix
==
0x40000000
)
r
=
0
;
/* for x < 2.0 */
else
if
(
ix
<
0x40000000
)
{
if
(
ix
<=
0x3f666666
)
{
/* lgamma(x) = lgamma(x+1)-log(x) */
r
=
-
__ieee754_logf
(
x
);
if
(
ix
>=
0x3f3b4a20
)
{
y
=
one
-
x
;
i
=
0
;}
else
if
(
ix
>=
0x3e6d3308
)
{
y
=
x
-
(
tc
-
one
);
i
=
1
;}
else
{
y
=
x
;
i
=
2
;}
}
else
{
r
=
zero
;
if
(
ix
>=
0x3fdda618
)
{
y
=
(
float
)
2
.
0
-
x
;
i
=
0
;}
/* [1.7316,2] */
else
if
(
ix
>=
0x3F9da620
)
{
y
=
x
-
tc
;
i
=
1
;}
/* [1.23,1.73] */
else
{
y
=
x
-
one
;
i
=
2
;}
}
switch
(
i
)
{
case
0
:
z
=
y
*
y
;
p1
=
a0
+
z
*
(
a2
+
z
*
(
a4
+
z
*
(
a6
+
z
*
(
a8
+
z
*
a10
))));
p2
=
z
*
(
a1
+
z
*
(
a3
+
z
*
(
a5
+
z
*
(
a7
+
z
*
(
a9
+
z
*
a11
)))));
p
=
y
*
p1
+
p2
;
r
+=
(
p
-
(
float
)
0
.
5
*
y
);
break
;
case
1
:
z
=
y
*
y
;
w
=
z
*
y
;
p1
=
t0
+
w
*
(
t3
+
w
*
(
t6
+
w
*
(
t9
+
w
*
t12
)));
/* parallel comp */
p2
=
t1
+
w
*
(
t4
+
w
*
(
t7
+
w
*
(
t10
+
w
*
t13
)));
p3
=
t2
+
w
*
(
t5
+
w
*
(
t8
+
w
*
(
t11
+
w
*
t14
)));
p
=
z
*
p1
-
(
tt
-
w
*
(
p2
+
y
*
p3
));
r
+=
(
tf
+
p
);
break
;
case
2
:
p1
=
y
*
(
u0
+
y
*
(
u1
+
y
*
(
u2
+
y
*
(
u3
+
y
*
(
u4
+
y
*
u5
)))));
p2
=
one
+
y
*
(
v1
+
y
*
(
v2
+
y
*
(
v3
+
y
*
(
v4
+
y
*
v5
))));
r
+=
(
-
(
float
)
0
.
5
*
y
+
p1
/
p2
);
}
}
else
if
(
ix
<
0x41000000
)
{
/* x < 8.0 */
i
=
(
__int32_t
)
x
;
t
=
zero
;
y
=
x
-
(
float
)
i
;
p
=
y
*
(
s0
+
y
*
(
s1
+
y
*
(
s2
+
y
*
(
s3
+
y
*
(
s4
+
y
*
(
s5
+
y
*
s6
))))));
q
=
one
+
y
*
(
r1
+
y
*
(
r2
+
y
*
(
r3
+
y
*
(
r4
+
y
*
(
r5
+
y
*
r6
)))));
r
=
half
*
y
+
p
/
q
;
z
=
one
;
/* lgamma(1+s) = log(s) + lgamma(s) */
switch
(
i
)
{
case
7
:
z
*=
(
y
+
(
float
)
6
.
0
);
/* FALLTHRU */
case
6
:
z
*=
(
y
+
(
float
)
5
.
0
);
/* FALLTHRU */
case
5
:
z
*=
(
y
+
(
float
)
4
.
0
);
/* FALLTHRU */
case
4
:
z
*=
(
y
+
(
float
)
3
.
0
);
/* FALLTHRU */
case
3
:
z
*=
(
y
+
(
float
)
2
.
0
);
/* FALLTHRU */
r
+=
__ieee754_logf
(
z
);
break
;
}
/* 8.0 <= x < 2**58 */
}
else
if
(
ix
<
0x5c800000
)
{
t
=
__ieee754_logf
(
x
);
z
=
one
/
x
;
y
=
z
*
z
;
w
=
w0
+
z
*
(
w1
+
y
*
(
w2
+
y
*
(
w3
+
y
*
(
w4
+
y
*
(
w5
+
y
*
w6
)))));
r
=
(
x
-
half
)
*
(
t
-
one
)
+
w
;
}
else
/* 2**58 <= x <= inf */
r
=
x
*
(
__ieee754_logf
(
x
)
-
one
);
if
(
hx
<
0
)
r
=
nadj
-
r
;
return
r
;
}
lib/libm/math.c
View file @
9ab94c46
...
...
@@ -117,13 +117,6 @@ float log10f(float x) { return logf(x) / (float)_M_LN10; }
float
tanhf
(
float
x
)
{
return
sinhf
(
x
)
/
coshf
(
x
);
}
// TODO we need import these functions from some library (eg musl or newlib)
float
tgammaf
(
float
x
)
{
return
0
.
0
;
}
float
lgammaf
(
float
x
)
{
return
0
.
0
;
}
float
erff
(
float
x
)
{
return
0
.
0
;
}
float
erfcf
(
float
x
)
{
return
0
.
0
;
}
float
ldexpf
(
float
x
,
int
exp
)
{
return
0
.
0
;
}
/*****************************************************************************/
/*****************************************************************************/
// __fpclassifyf from musl-0.9.15
...
...
lib/libm/sf_erf.c
0 → 100644
View file @
9ab94c46
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* These math functions are taken from newlib-nano-2, the newlib/libm/math
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
*
* Appropriate copyright headers are reproduced below.
*/
/* sf_erf.c -- float version of s_erf.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include
"fdlibm.h"
#define __ieee754_expf expf
#ifdef __v810__
#define const
#endif
#ifdef __STDC__
static
const
float
#else
static
float
#endif
tiny
=
1e-30
,
half
=
5.0000000000e-01
,
/* 0x3F000000 */
one
=
1.0000000000e+00
,
/* 0x3F800000 */
two
=
2.0000000000e+00
,
/* 0x40000000 */
/* c = (subfloat)0.84506291151 */
erx
=
8.4506291151e-01
,
/* 0x3f58560b */
/*
* Coefficients for approximation to erf on [0,0.84375]
*/
efx
=
1.2837916613e-01
,
/* 0x3e0375d4 */
efx8
=
1.0270333290e+00
,
/* 0x3f8375d4 */
pp0
=
1.2837916613e-01
,
/* 0x3e0375d4 */
pp1
=
-
3.2504209876e-01
,
/* 0xbea66beb */
pp2
=
-
2.8481749818e-02
,
/* 0xbce9528f */
pp3
=
-
5.7702702470e-03
,
/* 0xbbbd1489 */
pp4
=
-
2.3763017452e-05
,
/* 0xb7c756b1 */
qq1
=
3.9791721106e-01
,
/* 0x3ecbbbce */
qq2
=
6.5022252500e-02
,
/* 0x3d852a63 */
qq3
=
5.0813062117e-03
,
/* 0x3ba68116 */
qq4
=
1.3249473704e-04
,
/* 0x390aee49 */
qq5
=
-
3.9602282413e-06
,
/* 0xb684e21a */
/*
* Coefficients for approximation to erf in [0.84375,1.25]
*/
pa0
=
-
2.3621185683e-03
,
/* 0xbb1acdc6 */
pa1
=
4.1485610604e-01
,
/* 0x3ed46805 */
pa2
=
-
3.7220788002e-01
,
/* 0xbebe9208 */
pa3
=
3.1834661961e-01
,
/* 0x3ea2fe54 */
pa4
=
-
1.1089469492e-01
,
/* 0xbde31cc2 */
pa5
=
3.5478305072e-02
,
/* 0x3d1151b3 */
pa6
=
-
2.1663755178e-03
,
/* 0xbb0df9c0 */
qa1
=
1.0642088205e-01
,
/* 0x3dd9f331 */
qa2
=
5.4039794207e-01
,
/* 0x3f0a5785 */
qa3
=
7.1828655899e-02
,
/* 0x3d931ae7 */
qa4
=
1.2617121637e-01
,
/* 0x3e013307 */
qa5
=
1.3637083583e-02
,
/* 0x3c5f6e13 */
qa6
=
1.1984500103e-02
,
/* 0x3c445aa3 */
/*
* Coefficients for approximation to erfc in [1.25,1/0.35]
*/
ra0
=
-
9.8649440333e-03
,
/* 0xbc21a093 */
ra1
=
-
6.9385856390e-01
,
/* 0xbf31a0b7 */
ra2
=
-
1.0558626175e+01
,
/* 0xc128f022 */
ra3
=
-
6.2375331879e+01
,
/* 0xc2798057 */
ra4
=
-
1.6239666748e+02
,
/* 0xc322658c */
ra5
=
-
1.8460508728e+02
,
/* 0xc3389ae7 */
ra6
=
-
8.1287437439e+01
,
/* 0xc2a2932b */
ra7
=
-
9.8143291473e+00
,
/* 0xc11d077e */
sa1
=
1.9651271820e+01
,
/* 0x419d35ce */
sa2
=
1.3765776062e+02
,
/* 0x4309a863 */
sa3
=
4.3456588745e+02
,
/* 0x43d9486f */
sa4
=
6.4538726807e+02
,
/* 0x442158c9 */
sa5
=
4.2900814819e+02
,
/* 0x43d6810b */
sa6
=
1.0863500214e+02
,
/* 0x42d9451f */
sa7
=
6.5702495575e+00
,
/* 0x40d23f7c */
sa8
=
-
6.0424413532e-02
,
/* 0xbd777f97 */
/*
* Coefficients for approximation to erfc in [1/.35,28]
*/
rb0
=
-
9.8649431020e-03
,
/* 0xbc21a092 */
rb1
=
-
7.9928326607e-01
,
/* 0xbf4c9dd4 */
rb2
=
-
1.7757955551e+01
,
/* 0xc18e104b */
rb3
=
-
1.6063638306e+02
,
/* 0xc320a2ea */
rb4
=
-
6.3756646729e+02
,
/* 0xc41f6441 */
rb5
=
-
1.0250950928e+03
,
/* 0xc480230b */
rb6
=
-
4.8351919556e+02
,
/* 0xc3f1c275 */
sb1
=
3.0338060379e+01
,
/* 0x41f2b459 */
sb2
=
3.2579251099e+02
,
/* 0x43a2e571 */
sb3
=
1.5367296143e+03
,
/* 0x44c01759 */
sb4
=
3.1998581543e+03
,
/* 0x4547fdbb */
sb5
=
2.5530502930e+03
,
/* 0x451f90ce */
sb6
=
4.7452853394e+02
,
/* 0x43ed43a7 */
sb7
=
-
2.2440952301e+01
;
/* 0xc1b38712 */
#ifdef __STDC__
float
erff
(
float
x
)
#else
float
erff
(
x
)
float
x
;
#endif
{
__int32_t
hx
,
ix
,
i
;
float
R
,
S
,
P
,
Q
,
s
,
y
,
z
,
r
;
GET_FLOAT_WORD
(
hx
,
x
);
ix
=
hx
&
0x7fffffff
;
if
(
!
FLT_UWORD_IS_FINITE
(
ix
))
{
/* erf(nan)=nan */
i
=
((
__uint32_t
)
hx
>>
31
)
<<
1
;
return
(
float
)(
1
-
i
)
+
one
/
x
;
/* erf(+-inf)=+-1 */
}
if
(
ix
<
0x3f580000
)
{
/* |x|<0.84375 */
if
(
ix
<
0x31800000
)
{
/* |x|<2**-28 */
if
(
ix
<
0x04000000
)
/*avoid underflow */
return
(
float
)
0
.
125
*
((
float
)
8
.
0
*
x
+
efx8
*
x
);
return
x
+
efx
*
x
;
}
z
=
x
*
x
;
r
=
pp0
+
z
*
(
pp1
+
z
*
(
pp2
+
z
*
(
pp3
+
z
*
pp4
)));
s
=
one
+
z
*
(
qq1
+
z
*
(
qq2
+
z
*
(
qq3
+
z
*
(
qq4
+
z
*
qq5
))));
y
=
r
/
s
;
return
x
+
x
*
y
;
}
if
(
ix
<
0x3fa00000
)
{
/* 0.84375 <= |x| < 1.25 */
s
=
fabsf
(
x
)
-
one
;
P
=
pa0
+
s
*
(
pa1
+
s
*
(
pa2
+
s
*
(
pa3
+
s
*
(
pa4
+
s
*
(
pa5
+
s
*
pa6
)))));
Q
=
one
+
s
*
(
qa1
+
s
*
(
qa2
+
s
*
(
qa3
+
s
*
(
qa4
+
s
*
(
qa5
+
s
*
qa6
)))));
if
(
hx
>=
0
)
return
erx
+
P
/
Q
;
else
return
-
erx
-
P
/
Q
;
}
if
(
ix
>=
0x40c00000
)
{
/* inf>|x|>=6 */
if
(
hx
>=
0
)
return
one
-
tiny
;
else
return
tiny
-
one
;
}
x
=
fabsf
(
x
);
s
=
one
/
(
x
*
x
);
if
(
ix
<
0x4036DB6E
)
{
/* |x| < 1/0.35 */
R
=
ra0
+
s
*
(
ra1
+
s
*
(
ra2
+
s
*
(
ra3
+
s
*
(
ra4
+
s
*
(
ra5
+
s
*
(
ra6
+
s
*
ra7
))))));
S
=
one
+
s
*
(
sa1
+
s
*
(
sa2
+
s
*
(
sa3
+
s
*
(
sa4
+
s
*
(
sa5
+
s
*
(
sa6
+
s
*
(
sa7
+
s
*
sa8
)))))));
}
else
{
/* |x| >= 1/0.35 */
R
=
rb0
+
s
*
(
rb1
+
s
*
(
rb2
+
s
*
(
rb3
+
s
*
(
rb4
+
s
*
(
rb5
+
s
*
rb6
)))));
S
=
one
+
s
*
(
sb1
+
s
*
(
sb2
+
s
*
(
sb3
+
s
*
(
sb4
+
s
*
(
sb5
+
s
*
(
sb6
+
s
*
sb7
))))));
}
GET_FLOAT_WORD
(
ix
,
x
);
SET_FLOAT_WORD
(
z
,
ix
&
0xfffff000
);
r
=
__ieee754_expf
(
-
z
*
z
-
(
float
)
0
.
5625
)
*
__ieee754_expf
((
z
-
x
)
*
(
z
+
x
)
+
R
/
S
);
if
(
hx
>=
0
)
return
one
-
r
/
x
;
else
return
r
/
x
-
one
;
}
#ifdef __STDC__
float
erfcf
(
float
x
)
#else
float
erfcf
(
x
)
float
x
;
#endif
{
__int32_t
hx
,
ix
;
float
R
,
S
,
P
,
Q
,
s
,
y
,
z
,
r
;
GET_FLOAT_WORD
(
hx
,
x
);
ix
=
hx
&
0x7fffffff
;
if
(
!
FLT_UWORD_IS_FINITE
(
ix
))
{
/* erfc(nan)=nan */
/* erfc(+-inf)=0,2 */
return
(
float
)(((
__uint32_t
)
hx
>>
31
)
<<
1
)
+
one
/
x
;
}
if
(
ix
<
0x3f580000
)
{
/* |x|<0.84375 */
if
(
ix
<
0x23800000
)
/* |x|<2**-56 */
return
one
-
x
;
z
=
x
*
x
;
r
=
pp0
+
z
*
(
pp1
+
z
*
(
pp2
+
z
*
(
pp3
+
z
*
pp4
)));
s
=
one
+
z
*
(
qq1
+
z
*
(
qq2
+
z
*
(
qq3
+
z
*
(
qq4
+
z
*
qq5
))));
y
=
r
/
s
;
if
(
hx
<
0x3e800000
)
{
/* x<1/4 */
return
one
-
(
x
+
x
*
y
);
}
else
{
r
=
x
*
y
;
r
+=
(
x
-
half
);
return
half
-
r
;
}
}
if
(
ix
<
0x3fa00000
)
{
/* 0.84375 <= |x| < 1.25 */
s
=
fabsf
(
x
)
-
one
;
P
=
pa0
+
s
*
(
pa1
+
s
*
(
pa2
+
s
*
(
pa3
+
s
*
(
pa4
+
s
*
(
pa5
+
s
*
pa6
)))));
Q
=
one
+
s
*
(
qa1
+
s
*
(
qa2
+
s
*
(
qa3
+
s
*
(
qa4
+
s
*
(
qa5
+
s
*
qa6
)))));
if
(
hx
>=
0
)
{
z
=
one
-
erx
;
return
z
-
P
/
Q
;
}
else
{
z
=
erx
+
P
/
Q
;
return
one
+
z
;
}
}
if
(
ix
<
0x41e00000
)
{
/* |x|<28 */
x
=
fabsf
(
x
);
s
=
one
/
(
x
*
x
);
if
(
ix
<
0x4036DB6D
)
{
/* |x| < 1/.35 ~ 2.857143*/
R
=
ra0
+
s
*
(
ra1
+
s
*
(
ra2
+
s
*
(
ra3
+
s
*
(
ra4
+
s
*
(
ra5
+
s
*
(
ra6
+
s
*
ra7
))))));
S
=
one
+
s
*
(
sa1
+
s
*
(
sa2
+
s
*
(
sa3
+
s
*
(
sa4
+
s
*
(
sa5
+
s
*
(
sa6
+
s
*
(
sa7
+
s
*
sa8
)))))));
}
else
{
/* |x| >= 1/.35 ~ 2.857143 */
if
(
hx
<
0
&&
ix
>=
0x40c00000
)
return
two
-
tiny
;
/* x < -6 */
R
=
rb0
+
s
*
(
rb1
+
s
*
(
rb2
+
s
*
(
rb3
+
s
*
(
rb4
+
s
*
(
rb5
+
s
*
rb6
)))));
S
=
one
+
s
*
(
sb1
+
s
*
(
sb2
+
s
*
(
sb3
+
s
*
(
sb4
+
s
*
(
sb5
+
s
*
(
sb6
+
s
*
sb7
))))));
}
GET_FLOAT_WORD
(
ix
,
x
);
SET_FLOAT_WORD
(
z
,
ix
&
0xfffff000
);
r
=
__ieee754_expf
(
-
z
*
z
-
(
float
)
0
.
5625
)
*
__ieee754_expf
((
z
-
x
)
*
(
z
+
x
)
+
R
/
S
);
if
(
hx
>
0
)
return
r
/
x
;
else
return
two
-
r
/
x
;
}
else
{
if
(
hx
>
0
)
return
tiny
*
tiny
;
else
return
two
-
tiny
;
}
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double
erf
(
double
x
)
#else
double
erf
(
x
)
double
x
;
#endif
{
return
(
double
)
erff
((
float
)
x
);
}
#ifdef __STDC__
double
erfc
(
double
x
)
#else
double
erfc
(
x
)
double
x
;
#endif
{
return
(
double
)
erfcf
((
float
)
x
);
}
#endif
/* defined(_DOUBLE_IS_32BITS) */
lib/libm/sf_ldexp.c
0 → 100644
View file @
9ab94c46
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* These math functions are taken from newlib-nano-2, the newlib/libm/math
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
*
* Appropriate copyright headers are reproduced below.
*/
/* sf_ldexp.c -- float version of s_ldexp.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include
"fdlibm.h"
//#include <errno.h>
#ifdef __STDC__
float
ldexpf
(
float
value
,
int
exp
)
#else
float
ldexpf
(
value
,
exp
)
float
value
;
int
exp
;
#endif
{
if
(
!
finitef
(
value
)
||
value
==
(
float
)
0
.
0
)
return
value
;
value
=
scalbnf
(
value
,
exp
);
//if(!finitef(value)||value==(float)0.0) errno = ERANGE;
return
value
;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double
ldexp
(
double
value
,
int
exp
)
#else
double
ldexp
(
value
,
exp
)
double
value
;
int
exp
;
#endif
{
return
(
double
)
ldexpf
((
float
)
value
,
exp
);
}
#endif
/* defined(_DOUBLE_IS_32BITS) */
lib/libm/wf_lgamma.c
0 → 100644
View file @
9ab94c46
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* These math functions are taken from newlib-nano-2, the newlib/libm/math
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
*
* Appropriate copyright headers are reproduced below.
*/
/* wf_lgamma.c -- float version of w_lgamma.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*