Brought some musl math functions for wasm32.
This commit is contained in:
committed by
alexander-gorshenev
parent
c5d78b5b54
commit
9ec5b24832
@@ -0,0 +1,128 @@
|
|||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2014 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
Anthony G. Basile
|
||||||
|
Arvid Picciani
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Chris Spiegel
|
||||||
|
Emil Renner Berthing
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
John Spencer
|
||||||
|
Justin Cormack
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
Michael Forney
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Pierre Carrier
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Solar Designer
|
||||||
|
Strake
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Valentin Ochs
|
||||||
|
William Haddon
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/armel/memcpy.s) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/misc/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/misc/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The BSD PRNG implementation (src/prng/random.c) and XSI search API
|
||||||
|
(src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and
|
||||||
|
licensed under following terms: "Permission to use, copy, modify,
|
||||||
|
and/or distribute this code for any purpose with or without fee is
|
||||||
|
hereby granted. There is no warranty."
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain. Several files (crt)
|
||||||
|
were released into the public domain; others are licensed under the
|
||||||
|
standard MIT license terms at the top of this file. See individual
|
||||||
|
files for their copyright status.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
All public header files (include/* and arch/*/bits/*) should be
|
||||||
|
treated as Public Domain as they intentionally contain no content
|
||||||
|
which can be covered by copyright. Some source modules may fall in
|
||||||
|
this category as well. If you believe that a file is so trivial that
|
||||||
|
it should be in the Public Domain, please contact the authors and
|
||||||
|
request an explicit statement releasing it from copyright.
|
||||||
|
|
||||||
|
The following files are trivial, believed not to be copyrightable in
|
||||||
|
the first place, and hereby explicitly released to the Public Domain:
|
||||||
|
|
||||||
|
All public headers: include/*, arch/*/bits/*
|
||||||
|
Startup files: crt/*
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#ifndef _ENDIAN_H
|
||||||
|
#define _ENDIAN_H
|
||||||
|
|
||||||
|
#include <features.h>
|
||||||
|
|
||||||
|
#define __LITTLE_ENDIAN 1234
|
||||||
|
#define __BIG_ENDIAN 4321
|
||||||
|
#define __PDP_ENDIAN 3412
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__BYTE_ORDER__)
|
||||||
|
#define __BYTE_ORDER __BYTE_ORDER__
|
||||||
|
#else
|
||||||
|
#include <bits/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||||
|
|
||||||
|
#define BIG_ENDIAN __BIG_ENDIAN
|
||||||
|
#define LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||||
|
#define PDP_ENDIAN __PDP_ENDIAN
|
||||||
|
#define BYTE_ORDER __BYTE_ORDER
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static __inline uint16_t __bswap16(uint16_t __x)
|
||||||
|
{
|
||||||
|
return __x<<8 | __x>>8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline uint32_t __bswap32(uint32_t __x)
|
||||||
|
{
|
||||||
|
return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline uint64_t __bswap64(uint64_t __x)
|
||||||
|
{
|
||||||
|
return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
#define htobe16(x) __bswap16(x)
|
||||||
|
#define be16toh(x) __bswap16(x)
|
||||||
|
#define betoh16(x) __bswap16(x)
|
||||||
|
#define htobe32(x) __bswap32(x)
|
||||||
|
#define be32toh(x) __bswap32(x)
|
||||||
|
#define betoh32(x) __bswap32(x)
|
||||||
|
#define htobe64(x) __bswap64(x)
|
||||||
|
#define be64toh(x) __bswap64(x)
|
||||||
|
#define betoh64(x) __bswap64(x)
|
||||||
|
#define htole16(x) (uint16_t)(x)
|
||||||
|
#define le16toh(x) (uint16_t)(x)
|
||||||
|
#define letoh16(x) (uint16_t)(x)
|
||||||
|
#define htole32(x) (uint32_t)(x)
|
||||||
|
#define le32toh(x) (uint32_t)(x)
|
||||||
|
#define letoh32(x) (uint32_t)(x)
|
||||||
|
#define htole64(x) (uint64_t)(x)
|
||||||
|
#define le64toh(x) (uint64_t)(x)
|
||||||
|
#define letoh64(x) (uint64_t)(x)
|
||||||
|
#else
|
||||||
|
#define htobe16(x) (uint16_t)(x)
|
||||||
|
#define be16toh(x) (uint16_t)(x)
|
||||||
|
#define betoh16(x) (uint16_t)(x)
|
||||||
|
#define htobe32(x) (uint32_t)(x)
|
||||||
|
#define be32toh(x) (uint32_t)(x)
|
||||||
|
#define betoh32(x) (uint32_t)(x)
|
||||||
|
#define htobe64(x) (uint64_t)(x)
|
||||||
|
#define be64toh(x) (uint64_t)(x)
|
||||||
|
#define betoh64(x) (uint64_t)(x)
|
||||||
|
#define htole16(x) __bswap16(x)
|
||||||
|
#define le16toh(x) __bswap16(x)
|
||||||
|
#define letoh16(x) __bswap16(x)
|
||||||
|
#define htole32(x) __bswap32(x)
|
||||||
|
#define le32toh(x) __bswap32(x)
|
||||||
|
#define letoh32(x) __bswap32(x)
|
||||||
|
#define htole64(x) __bswap64(x)
|
||||||
|
#define le64toh(x) __bswap64(x)
|
||||||
|
#define letoh64(x) __bswap64(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
double fmod(double x, double y)
|
||||||
|
{
|
||||||
|
union {double f; uint64_t i;} ux = {x}, uy = {y};
|
||||||
|
int ex = ux.i>>52 & 0x7ff;
|
||||||
|
int ey = uy.i>>52 & 0x7ff;
|
||||||
|
int sx = ux.i>>63;
|
||||||
|
uint64_t i;
|
||||||
|
|
||||||
|
/* in the followings uxi should be ux.i, but then gcc wrongly adds */
|
||||||
|
/* float load/store to inner loops ruining performance and code size */
|
||||||
|
uint64_t uxi = ux.i;
|
||||||
|
|
||||||
|
if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
|
||||||
|
return (x*y)/(x*y);
|
||||||
|
if (uxi<<1 <= uy.i<<1) {
|
||||||
|
if (uxi<<1 == uy.i<<1)
|
||||||
|
return 0*x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normalize x and y */
|
||||||
|
if (!ex) {
|
||||||
|
for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
|
||||||
|
uxi <<= -ex + 1;
|
||||||
|
} else {
|
||||||
|
uxi &= -1ULL >> 12;
|
||||||
|
uxi |= 1ULL << 52;
|
||||||
|
}
|
||||||
|
if (!ey) {
|
||||||
|
for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
|
||||||
|
uy.i <<= -ey + 1;
|
||||||
|
} else {
|
||||||
|
uy.i &= -1ULL >> 12;
|
||||||
|
uy.i |= 1ULL << 52;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* x mod y */
|
||||||
|
for (; ex > ey; ex--) {
|
||||||
|
i = uxi - uy.i;
|
||||||
|
if (i >> 63 == 0) {
|
||||||
|
if (i == 0)
|
||||||
|
return 0*x;
|
||||||
|
uxi = i;
|
||||||
|
}
|
||||||
|
uxi <<= 1;
|
||||||
|
}
|
||||||
|
i = uxi - uy.i;
|
||||||
|
if (i >> 63 == 0) {
|
||||||
|
if (i == 0)
|
||||||
|
return 0*x;
|
||||||
|
uxi = i;
|
||||||
|
}
|
||||||
|
for (; uxi>>52 == 0; uxi <<= 1, ex--);
|
||||||
|
|
||||||
|
/* scale result */
|
||||||
|
if (ex > 0) {
|
||||||
|
uxi -= 1ULL << 52;
|
||||||
|
uxi |= (uint64_t)ex << 52;
|
||||||
|
} else {
|
||||||
|
uxi >>= -ex + 1;
|
||||||
|
}
|
||||||
|
uxi |= (uint64_t)sx << 63;
|
||||||
|
ux.i = uxi;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
float fmodf(float x, float y)
|
||||||
|
{
|
||||||
|
union {float f; uint32_t i;} ux = {x}, uy = {y};
|
||||||
|
int ex = ux.i>>23 & 0xff;
|
||||||
|
int ey = uy.i>>23 & 0xff;
|
||||||
|
uint32_t sx = ux.i & 0x80000000;
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t uxi = ux.i;
|
||||||
|
|
||||||
|
if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
|
||||||
|
return (x*y)/(x*y);
|
||||||
|
if (uxi<<1 <= uy.i<<1) {
|
||||||
|
if (uxi<<1 == uy.i<<1)
|
||||||
|
return 0*x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normalize x and y */
|
||||||
|
if (!ex) {
|
||||||
|
for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
|
||||||
|
uxi <<= -ex + 1;
|
||||||
|
} else {
|
||||||
|
uxi &= -1U >> 9;
|
||||||
|
uxi |= 1U << 23;
|
||||||
|
}
|
||||||
|
if (!ey) {
|
||||||
|
for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
|
||||||
|
uy.i <<= -ey + 1;
|
||||||
|
} else {
|
||||||
|
uy.i &= -1U >> 9;
|
||||||
|
uy.i |= 1U << 23;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* x mod y */
|
||||||
|
for (; ex > ey; ex--) {
|
||||||
|
i = uxi - uy.i;
|
||||||
|
if (i >> 31 == 0) {
|
||||||
|
if (i == 0)
|
||||||
|
return 0*x;
|
||||||
|
uxi = i;
|
||||||
|
}
|
||||||
|
uxi <<= 1;
|
||||||
|
}
|
||||||
|
i = uxi - uy.i;
|
||||||
|
if (i >> 31 == 0) {
|
||||||
|
if (i == 0)
|
||||||
|
return 0*x;
|
||||||
|
uxi = i;
|
||||||
|
}
|
||||||
|
for (; uxi>>23 == 0; uxi <<= 1, ex--);
|
||||||
|
|
||||||
|
/* scale result up */
|
||||||
|
if (ex > 0) {
|
||||||
|
uxi -= 1U << 23;
|
||||||
|
uxi |= (uint32_t)ex << 23;
|
||||||
|
} else {
|
||||||
|
uxi >>= -ex + 1;
|
||||||
|
}
|
||||||
|
uxi |= sx;
|
||||||
|
ux.i = uxi;
|
||||||
|
return ux.f;
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
* 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.
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBM_H
|
||||||
|
#define _LIBM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <math.h>
|
||||||
|
//#include "endian.h"
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
union ldshape {
|
||||||
|
long double f;
|
||||||
|
struct {
|
||||||
|
uint64_t m;
|
||||||
|
uint16_t se;
|
||||||
|
} i;
|
||||||
|
};
|
||||||
|
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
union ldshape {
|
||||||
|
long double f;
|
||||||
|
struct {
|
||||||
|
uint64_t lo;
|
||||||
|
uint32_t mid;
|
||||||
|
uint16_t top;
|
||||||
|
uint16_t se;
|
||||||
|
} i;
|
||||||
|
struct {
|
||||||
|
uint64_t lo;
|
||||||
|
uint64_t hi;
|
||||||
|
} i2;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#error Unsupported long double representation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
/*
|
||||||
|
* asm.js doesn't have user-accessible floating point exceptions, so there's
|
||||||
|
* no point in trying to force expression evaluations to produce them.
|
||||||
|
*/
|
||||||
|
#define FORCE_EVAL(x)
|
||||||
|
#else
|
||||||
|
#define FORCE_EVAL(x) do { \
|
||||||
|
if (sizeof(x) == sizeof(float)) { \
|
||||||
|
volatile float __x; \
|
||||||
|
__x = (x); \
|
||||||
|
} else if (sizeof(x) == sizeof(double)) { \
|
||||||
|
volatile double __x; \
|
||||||
|
__x = (x); \
|
||||||
|
} else { \
|
||||||
|
volatile long double __x; \
|
||||||
|
__x = (x); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get two 32 bit ints from a double. */
|
||||||
|
#define EXTRACT_WORDS(hi,lo,d) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
(hi) = __u.i >> 32; \
|
||||||
|
(lo) = (uint32_t)__u.i; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Get the more significant 32 bit int from a double. */
|
||||||
|
#define GET_HIGH_WORD(hi,d) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
(hi) = __u.i >> 32; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Get the less significant 32 bit int from a double. */
|
||||||
|
#define GET_LOW_WORD(lo,d) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
(lo) = (uint32_t)__u.i; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Set a double from two 32 bit ints. */
|
||||||
|
#define INSERT_WORDS(d,hi,lo) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \
|
||||||
|
(d) = __u.f; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Set the more significant 32 bits of a double from an int. */
|
||||||
|
#define SET_HIGH_WORD(d,hi) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
__u.i &= 0xffffffff; \
|
||||||
|
__u.i |= (uint64_t)(hi) << 32; \
|
||||||
|
(d) = __u.f; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Set the less significant 32 bits of a double from an int. */
|
||||||
|
#define SET_LOW_WORD(d,lo) \
|
||||||
|
do { \
|
||||||
|
union {double f; uint64_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
__u.i &= 0xffffffff00000000ull; \
|
||||||
|
__u.i |= (uint32_t)(lo); \
|
||||||
|
(d) = __u.f; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Get a 32 bit int from a float. */
|
||||||
|
#define GET_FLOAT_WORD(w,d) \
|
||||||
|
do { \
|
||||||
|
union {float f; uint32_t i;} __u; \
|
||||||
|
__u.f = (d); \
|
||||||
|
(w) = __u.i; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Set a float from a 32 bit int. */
|
||||||
|
#define SET_FLOAT_WORD(d,w) \
|
||||||
|
do { \
|
||||||
|
union {float f; uint32_t i;} __u; \
|
||||||
|
__u.i = (w); \
|
||||||
|
(d) = __u.f; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* fdlibm kernel functions */
|
||||||
|
|
||||||
|
int __rem_pio2_large(double*,double*,int,int,int);
|
||||||
|
|
||||||
|
int __rem_pio2(double,double*);
|
||||||
|
double __sin(double,double,int);
|
||||||
|
double __cos(double,double);
|
||||||
|
double __tan(double,double,int);
|
||||||
|
double __expo2(double);
|
||||||
|
|
||||||
|
int __rem_pio2f(float,double*);
|
||||||
|
float __sindf(double);
|
||||||
|
float __cosdf(double);
|
||||||
|
float __tandf(double,int);
|
||||||
|
float __expo2f(float);
|
||||||
|
|
||||||
|
int __rem_pio2l(long double, long double *);
|
||||||
|
long double __sinl(long double, long double, int);
|
||||||
|
long double __cosl(long double, long double);
|
||||||
|
long double __tanl(long double, long double, int);
|
||||||
|
|
||||||
|
/* polynomial evaluation */
|
||||||
|
long double __polevll(long double, const long double *, int);
|
||||||
|
long double __p1evll(long double, const long double *, int);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
double scalbn(double x, int n)
|
||||||
|
{
|
||||||
|
union {double f; uint64_t i;} u;
|
||||||
|
double_t y = x;
|
||||||
|
|
||||||
|
if (n > 1023) {
|
||||||
|
y *= 0x1p1023;
|
||||||
|
n -= 1023;
|
||||||
|
if (n > 1023) {
|
||||||
|
y *= 0x1p1023;
|
||||||
|
n -= 1023;
|
||||||
|
if (n > 1023)
|
||||||
|
n = 1023;
|
||||||
|
}
|
||||||
|
} else if (n < -1022) {
|
||||||
|
y *= 0x1p-1022;
|
||||||
|
n += 1022;
|
||||||
|
if (n < -1022) {
|
||||||
|
y *= 0x1p-1022;
|
||||||
|
n += 1022;
|
||||||
|
if (n < -1022)
|
||||||
|
n = -1022;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.i = (uint64_t)(0x3ff+n)<<52;
|
||||||
|
x = y * u.f;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user