mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Use ARM's faster math functions on non-tiny builds
This commit is contained in:
parent
3c10fb5580
commit
4814b6bdf8
58 changed files with 3760 additions and 361 deletions
34
libc/tinymath/__math_divzero.c
Normal file
34
libc/tinymath/__math_divzero.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
double __math_divzero(uint32_t sign)
|
||||
{
|
||||
return fp_barrier(sign ? -1.0 : 1.0) / 0.0;
|
||||
}
|
34
libc/tinymath/__math_divzerof.c
Normal file
34
libc/tinymath/__math_divzerof.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
float __math_divzerof(uint32_t sign)
|
||||
{
|
||||
return fp_barrierf(sign ? -1.0f : 1.0f) / 0.0f;
|
||||
}
|
34
libc/tinymath/__math_invalid.c
Normal file
34
libc/tinymath/__math_invalid.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
double __math_invalid(double x)
|
||||
{
|
||||
return (x - x) / (x - x);
|
||||
}
|
34
libc/tinymath/__math_invalidf.c
Normal file
34
libc/tinymath/__math_invalidf.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
float __math_invalidf(float x)
|
||||
{
|
||||
return (x - x) / (x - x);
|
||||
}
|
34
libc/tinymath/__math_oflow.c
Normal file
34
libc/tinymath/__math_oflow.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
double __math_oflow(uint32_t sign)
|
||||
{
|
||||
return __math_xflow(sign, 0x1p769);
|
||||
}
|
34
libc/tinymath/__math_oflowf.c
Normal file
34
libc/tinymath/__math_oflowf.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
float __math_oflowf(uint32_t sign)
|
||||
{
|
||||
return __math_xflowf(sign, 0x1p97f);
|
||||
}
|
34
libc/tinymath/__math_uflow.c
Normal file
34
libc/tinymath/__math_uflow.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
double __math_uflow(uint32_t sign)
|
||||
{
|
||||
return __math_xflow(sign, 0x1p-767);
|
||||
}
|
34
libc/tinymath/__math_uflowf.c
Normal file
34
libc/tinymath/__math_uflowf.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
float __math_uflowf(uint32_t sign)
|
||||
{
|
||||
return __math_xflowf(sign, 0x1p-95f);
|
||||
}
|
34
libc/tinymath/__math_xflow.c
Normal file
34
libc/tinymath/__math_xflow.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
double __math_xflow(uint32_t sign, double y)
|
||||
{
|
||||
return eval_as_double(fp_barrier(sign ? -y : y) * y);
|
||||
}
|
34
libc/tinymath/__math_xflowf.c
Normal file
34
libc/tinymath/__math_xflowf.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/internal.h"
|
||||
// clang-format off
|
||||
|
||||
float __math_xflowf(uint32_t sign, float y)
|
||||
{
|
||||
return eval_as_float(fp_barrierf(sign ? -y : y) * y);
|
||||
}
|
|
@ -1,13 +1,9 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_COMPLEX_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_COMPLEX_INTERNAL_H_
|
||||
#include "libc/tinymath/internal.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
|
||||
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
|
||||
#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
|
||||
#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
|
||||
|
||||
#define EXTRACT_WORDS(hi, lo, d) \
|
||||
do { \
|
||||
uint64_t __u = asuint64(d); \
|
||||
|
@ -30,11 +26,9 @@ do { \
|
|||
(d) = asdouble(((uint64_t)(hi) << 32) | (uint32_t)(lo)); \
|
||||
} while (0)
|
||||
|
||||
#define SET_HIGH_WORD(d,hi) \
|
||||
INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
|
||||
#define SET_HIGH_WORD(d, hi) INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
|
||||
|
||||
#define SET_LOW_WORD(d,lo) \
|
||||
INSERT_WORDS(d, asuint64(d)>>32, lo)
|
||||
#define SET_LOW_WORD(d, lo) INSERT_WORDS(d, asuint64(d) >> 32, lo)
|
||||
|
||||
#define GET_FLOAT_WORD(w, d) \
|
||||
do { \
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/kernel.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
fdlibm (fdlibm license)\\n\
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns 𝑒^x.
|
||||
//
|
||||
|
@ -25,3 +26,5 @@
|
|||
exp: ezlea expl,ax
|
||||
jmp _d2ld2
|
||||
.endfn exp,globl
|
||||
|
||||
#endif /* TINY */
|
173
libc/tinymath/exp.c
Normal file
173
libc/tinymath/exp.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/exp_data.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Double-precision e^x function.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << EXP_TABLE_BITS)
|
||||
#define InvLn2N __exp_data.invln2N
|
||||
#define NegLn2hiN __exp_data.negln2hiN
|
||||
#define NegLn2loN __exp_data.negln2loN
|
||||
#define Shift __exp_data.shift
|
||||
#define T __exp_data.tab
|
||||
#define C2 __exp_data.poly[5 - EXP_POLY_ORDER]
|
||||
#define C3 __exp_data.poly[6 - EXP_POLY_ORDER]
|
||||
#define C4 __exp_data.poly[7 - EXP_POLY_ORDER]
|
||||
#define C5 __exp_data.poly[8 - EXP_POLY_ORDER]
|
||||
|
||||
/* Handle cases that may overflow or underflow when computing the result that
|
||||
is scale*(1+TMP) without intermediate rounding. The bit representation of
|
||||
scale is in SBITS, however it has a computed exponent that may have
|
||||
overflown into the sign bit so that needs to be adjusted before using it as
|
||||
a double. (int32_t)KI is the k used in the argument reduction and exponent
|
||||
adjustment of scale, positive k here means the result may overflow and
|
||||
negative k means the result may underflow. */
|
||||
static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
|
||||
{
|
||||
double_t scale, y;
|
||||
|
||||
if ((ki & 0x80000000) == 0) {
|
||||
/* k > 0, the exponent of scale might have overflowed by <= 460. */
|
||||
sbits -= 1009ull << 52;
|
||||
scale = asdouble(sbits);
|
||||
y = 0x1p1009 * (scale + scale * tmp);
|
||||
return eval_as_double(y);
|
||||
}
|
||||
/* k < 0, need special care in the subnormal range. */
|
||||
sbits += 1022ull << 52;
|
||||
scale = asdouble(sbits);
|
||||
y = scale + scale * tmp;
|
||||
if (y < 1.0) {
|
||||
/* Round y to the right precision before scaling it into the subnormal
|
||||
range to avoid double rounding that can cause 0.5+E/2 ulp error where
|
||||
E is the worst-case ulp error outside the subnormal range. So this
|
||||
is only useful if the goal is better than 1 ulp worst-case error. */
|
||||
double_t hi, lo;
|
||||
lo = scale - y + scale * tmp;
|
||||
hi = 1.0 + y;
|
||||
lo = 1.0 - hi + y + lo;
|
||||
y = eval_as_double(hi + lo) - 1.0;
|
||||
/* Avoid -0.0 with downward rounding. */
|
||||
if (WANT_ROUNDING && y == 0.0)
|
||||
y = 0.0;
|
||||
/* The underflow exception needs to be signaled explicitly. */
|
||||
fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);
|
||||
}
|
||||
y = 0x1p-1022 * y;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
|
||||
/* Top 12 bits of a double (sign and exponent bits). */
|
||||
static inline uint32_t top12(double x)
|
||||
{
|
||||
return asuint64(x) >> 52;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 𝑒^x.
|
||||
*/
|
||||
double exp(double x)
|
||||
{
|
||||
uint32_t abstop;
|
||||
uint64_t ki, idx, top, sbits;
|
||||
double_t kd, z, r, r2, scale, tail, tmp;
|
||||
|
||||
abstop = top12(x) & 0x7ff;
|
||||
if (UNLIKELY(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) {
|
||||
if (abstop - top12(0x1p-54) >= 0x80000000)
|
||||
/* Avoid spurious underflow for tiny x. */
|
||||
/* Note: 0 is common input. */
|
||||
return WANT_ROUNDING ? 1.0 + x : 1.0;
|
||||
if (abstop >= top12(1024.0)) {
|
||||
if (asuint64(x) == asuint64(-INFINITY))
|
||||
return 0.0;
|
||||
if (abstop >= top12(INFINITY))
|
||||
return 1.0 + x;
|
||||
if (asuint64(x) >> 63)
|
||||
return __math_uflow(0);
|
||||
else
|
||||
return __math_oflow(0);
|
||||
}
|
||||
/* Large x is special cased below. */
|
||||
abstop = 0;
|
||||
}
|
||||
|
||||
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
||||
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
||||
z = InvLn2N * x;
|
||||
#if TOINT_INTRINSICS
|
||||
kd = roundtoint(z);
|
||||
ki = converttoint(z);
|
||||
#elif EXP_USE_TOINT_NARROW
|
||||
/* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */
|
||||
kd = eval_as_double(z + Shift);
|
||||
ki = asuint64(kd) >> 16;
|
||||
kd = (double_t)(int32_t)ki;
|
||||
#else
|
||||
/* z - kd is in [-1, 1] in non-nearest rounding modes. */
|
||||
kd = eval_as_double(z + Shift);
|
||||
ki = asuint64(kd);
|
||||
kd -= Shift;
|
||||
#endif
|
||||
r = x + kd * NegLn2hiN + kd * NegLn2loN;
|
||||
/* 2^(k/N) ~= scale * (1 + tail). */
|
||||
idx = 2 * (ki % N);
|
||||
top = ki << (52 - EXP_TABLE_BITS);
|
||||
tail = asdouble(T[idx]);
|
||||
/* This is only a valid scale when -1023*N < k < 1024*N. */
|
||||
sbits = T[idx + 1] + top;
|
||||
/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */
|
||||
/* Evaluation is optimized assuming superscalar pipelined execution. */
|
||||
r2 = r * r;
|
||||
/* Without fma the worst case error is 0.25/N ulp larger. */
|
||||
/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */
|
||||
tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
|
||||
if (UNLIKELY(abstop == 0))
|
||||
return specialcase(tmp, sbits, ki);
|
||||
scale = asdouble(sbits);
|
||||
/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
|
||||
is no spurious underflow here even without fma. */
|
||||
return eval_as_double(scale + scale * tmp);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns 2^𝑥.
|
||||
//
|
||||
|
@ -25,3 +26,5 @@
|
|||
exp2: ezlea exp2l,ax
|
||||
jmp _d2ld2
|
||||
.endfn exp2,globl
|
||||
|
||||
#endif /* TINY */
|
160
libc/tinymath/exp2.c
Normal file
160
libc/tinymath/exp2.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/exp_data.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Double-precision 2^x function.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << EXP_TABLE_BITS)
|
||||
#define Shift __exp_data.exp2_shift
|
||||
#define T __exp_data.tab
|
||||
#define C1 __exp_data.exp2_poly[0]
|
||||
#define C2 __exp_data.exp2_poly[1]
|
||||
#define C3 __exp_data.exp2_poly[2]
|
||||
#define C4 __exp_data.exp2_poly[3]
|
||||
#define C5 __exp_data.exp2_poly[4]
|
||||
|
||||
/* Handle cases that may overflow or underflow when computing the result that
|
||||
is scale*(1+TMP) without intermediate rounding. The bit representation of
|
||||
scale is in SBITS, however it has a computed exponent that may have
|
||||
overflown into the sign bit so that needs to be adjusted before using it as
|
||||
a double. (int32_t)KI is the k used in the argument reduction and exponent
|
||||
adjustment of scale, positive k here means the result may overflow and
|
||||
negative k means the result may underflow. */
|
||||
static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
|
||||
{
|
||||
double_t scale, y;
|
||||
|
||||
if ((ki & 0x80000000) == 0) {
|
||||
/* k > 0, the exponent of scale might have overflowed by 1. */
|
||||
sbits -= 1ull << 52;
|
||||
scale = asdouble(sbits);
|
||||
y = 2 * (scale + scale * tmp);
|
||||
return eval_as_double(y);
|
||||
}
|
||||
/* k < 0, need special care in the subnormal range. */
|
||||
sbits += 1022ull << 52;
|
||||
scale = asdouble(sbits);
|
||||
y = scale + scale * tmp;
|
||||
if (y < 1.0) {
|
||||
/* Round y to the right precision before scaling it into the subnormal
|
||||
range to avoid double rounding that can cause 0.5+E/2 ulp error where
|
||||
E is the worst-case ulp error outside the subnormal range. So this
|
||||
is only useful if the goal is better than 1 ulp worst-case error. */
|
||||
double_t hi, lo;
|
||||
lo = scale - y + scale * tmp;
|
||||
hi = 1.0 + y;
|
||||
lo = 1.0 - hi + y + lo;
|
||||
y = eval_as_double(hi + lo) - 1.0;
|
||||
/* Avoid -0.0 with downward rounding. */
|
||||
if (WANT_ROUNDING && y == 0.0)
|
||||
y = 0.0;
|
||||
/* The underflow exception needs to be signaled explicitly. */
|
||||
fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);
|
||||
}
|
||||
y = 0x1p-1022 * y;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
|
||||
/* Top 12 bits of a double (sign and exponent bits). */
|
||||
static inline uint32_t top12(double x)
|
||||
{
|
||||
return asuint64(x) >> 52;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 2^𝑥.
|
||||
*/
|
||||
double exp2(double x)
|
||||
{
|
||||
uint32_t abstop;
|
||||
uint64_t ki, idx, top, sbits;
|
||||
double_t kd, r, r2, scale, tail, tmp;
|
||||
|
||||
abstop = top12(x) & 0x7ff;
|
||||
if (UNLIKELY(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) {
|
||||
if (abstop - top12(0x1p-54) >= 0x80000000)
|
||||
/* Avoid spurious underflow for tiny x. */
|
||||
/* Note: 0 is common input. */
|
||||
return WANT_ROUNDING ? 1.0 + x : 1.0;
|
||||
if (abstop >= top12(1024.0)) {
|
||||
if (asuint64(x) == asuint64(-INFINITY))
|
||||
return 0.0;
|
||||
if (abstop >= top12(INFINITY))
|
||||
return 1.0 + x;
|
||||
if (!(asuint64(x) >> 63))
|
||||
return __math_oflow(0);
|
||||
else if (asuint64(x) >= asuint64(-1075.0))
|
||||
return __math_uflow(0);
|
||||
}
|
||||
if (2 * asuint64(x) > 2 * asuint64(928.0))
|
||||
/* Large x is special cased below. */
|
||||
abstop = 0;
|
||||
}
|
||||
|
||||
/* exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)]. */
|
||||
/* x = k/N + r, with int k and r in [-1/2N, 1/2N]. */
|
||||
kd = eval_as_double(x + Shift);
|
||||
ki = asuint64(kd); /* k. */
|
||||
kd -= Shift; /* k/N for int k. */
|
||||
r = x - kd;
|
||||
/* 2^(k/N) ~= scale * (1 + tail). */
|
||||
idx = 2 * (ki % N);
|
||||
top = ki << (52 - EXP_TABLE_BITS);
|
||||
tail = asdouble(T[idx]);
|
||||
/* This is only a valid scale when -1023*N < k < 1024*N. */
|
||||
sbits = T[idx + 1] + top;
|
||||
/* exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1). */
|
||||
/* Evaluation is optimized assuming superscalar pipelined execution. */
|
||||
r2 = r * r;
|
||||
/* Without fma the worst case error is 0.5/N ulp larger. */
|
||||
/* Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp. */
|
||||
tmp = tail + r * C1 + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
|
||||
if (UNLIKELY(abstop == 0))
|
||||
return specialcase(tmp, sbits, ki);
|
||||
scale = asdouble(sbits);
|
||||
/* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there
|
||||
is no spurious underflow here even without fma. */
|
||||
return eval_as_double(scale + scale * tmp);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns 2^𝑥.
|
||||
//
|
||||
|
@ -26,3 +27,5 @@ exp2f:
|
|||
ezlea exp2l,ax
|
||||
jmp _f2ld2
|
||||
.endfn exp2f,globl
|
||||
|
||||
#endif /* TINY */
|
108
libc/tinymath/exp2f.c
Normal file
108
libc/tinymath/exp2f.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/exp2f_data.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Single-precision 2^x function.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
EXP2F_TABLE_BITS = 5
|
||||
EXP2F_POLY_ORDER = 3
|
||||
|
||||
ULP error: 0.502 (nearest rounding.)
|
||||
Relative error: 1.69 * 2^-34 in [-1/64, 1/64] (before rounding.)
|
||||
Wrong count: 168353 (all nearest rounding wrong results with fma.)
|
||||
Non-nearest ULP error: 1 (rounded ULP error)
|
||||
*/
|
||||
|
||||
#define N (1 << EXP2F_TABLE_BITS)
|
||||
#define T __exp2f_data.tab
|
||||
#define C __exp2f_data.poly
|
||||
#define SHIFT __exp2f_data.shift_scaled
|
||||
|
||||
static inline uint32_t top12(float x)
|
||||
{
|
||||
return asuint(x) >> 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 2^𝑥.
|
||||
*/
|
||||
float exp2f(float x)
|
||||
{
|
||||
uint32_t abstop;
|
||||
uint64_t ki, t;
|
||||
double_t kd, xd, z, r, r2, y, s;
|
||||
|
||||
xd = (double_t)x;
|
||||
abstop = top12(x) & 0x7ff;
|
||||
if (UNLIKELY(abstop >= top12(128.0f))) {
|
||||
/* |x| >= 128 or x is nan. */
|
||||
if (asuint(x) == asuint(-INFINITY))
|
||||
return 0.0f;
|
||||
if (abstop >= top12(INFINITY))
|
||||
return x + x;
|
||||
if (x > 0.0f)
|
||||
return __math_oflowf(0);
|
||||
if (x <= -150.0f)
|
||||
return __math_uflowf(0);
|
||||
}
|
||||
|
||||
/* x = k/N + r with r in [-1/(2N), 1/(2N)] and int k. */
|
||||
kd = eval_as_double(xd + SHIFT);
|
||||
ki = asuint64(kd);
|
||||
kd -= SHIFT; /* k/N for int k. */
|
||||
r = xd - kd;
|
||||
|
||||
/* exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */
|
||||
t = T[ki % N];
|
||||
t += ki << (52 - EXP2F_TABLE_BITS);
|
||||
s = asdouble(t);
|
||||
z = C[0] * r + C[1];
|
||||
r2 = r * r;
|
||||
y = C[2] * r + 1;
|
||||
y = z * r2 + y;
|
||||
y = y * s;
|
||||
return eval_as_float(y);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
68
libc/tinymath/exp2f_data.c
Normal file
68
libc/tinymath/exp2f_data.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/exp2f_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Shared data between expf, exp2f and powf.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << EXP2F_TABLE_BITS)
|
||||
|
||||
const struct exp2f_data __exp2f_data = {
|
||||
/* tab[i] = uint(2^(i/N)) - (i << 52-BITS)
|
||||
used for computing 2^(k/N) for an int |k| < 150 N as
|
||||
double(tab[k%N] + (k << 52-BITS)) */
|
||||
.tab = {
|
||||
0x3ff0000000000000, 0x3fefd9b0d3158574, 0x3fefb5586cf9890f, 0x3fef9301d0125b51,
|
||||
0x3fef72b83c7d517b, 0x3fef54873168b9aa, 0x3fef387a6e756238, 0x3fef1e9df51fdee1,
|
||||
0x3fef06fe0a31b715, 0x3feef1a7373aa9cb, 0x3feedea64c123422, 0x3feece086061892d,
|
||||
0x3feebfdad5362a27, 0x3feeb42b569d4f82, 0x3feeab07dd485429, 0x3feea47eb03a5585,
|
||||
0x3feea09e667f3bcd, 0x3fee9f75e8ec5f74, 0x3feea11473eb0187, 0x3feea589994cce13,
|
||||
0x3feeace5422aa0db, 0x3feeb737b0cdc5e5, 0x3feec49182a3f090, 0x3feed503b23e255d,
|
||||
0x3feee89f995ad3ad, 0x3feeff76f2fb5e47, 0x3fef199bdd85529c, 0x3fef3720dcef9069,
|
||||
0x3fef5818dcfba487, 0x3fef7c97337b9b5f, 0x3fefa4afa2a490da, 0x3fefd0765b6e4540,
|
||||
},
|
||||
.shift_scaled = 0x1.8p+52 / N,
|
||||
.poly = {
|
||||
0x1.c6af84b912394p-5, 0x1.ebfce50fac4f3p-3, 0x1.62e42ff0c52d6p-1,
|
||||
},
|
||||
.shift = 0x1.8p+52,
|
||||
.invln2_scaled = 0x1.71547652b82fep+0 * N,
|
||||
.poly_scaled = {
|
||||
0x1.c6af84b912394p-5/N/N/N, 0x1.ebfce50fac4f3p-3/N/N, 0x1.62e42ff0c52d6p-1/N,
|
||||
},
|
||||
};
|
21
libc/tinymath/exp2f_data.internal.h
Normal file
21
libc/tinymath/exp2f_data.internal.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_EXP2F_DATA_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_EXP2F_DATA_INTERNAL_H_
|
||||
|
||||
#define EXP2F_TABLE_BITS 5
|
||||
#define EXP2F_POLY_ORDER 3
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct exp2f_data {
|
||||
uint64_t tab[1 << EXP2F_TABLE_BITS];
|
||||
double shift_scaled;
|
||||
double poly[EXP2F_POLY_ORDER];
|
||||
double shift;
|
||||
double invln2_scaled;
|
||||
double poly_scaled[EXP2F_POLY_ORDER];
|
||||
} __exp2f_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_EXP2F_DATA_INTERNAL_H_ */
|
215
libc/tinymath/exp_data.c
Normal file
215
libc/tinymath/exp_data.c
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/exp_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Shared data between exp, exp2 and pow.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << EXP_TABLE_BITS)
|
||||
|
||||
const struct exp_data __exp_data = {
|
||||
// N/ln2
|
||||
.invln2N = 0x1.71547652b82fep0 * N,
|
||||
// -ln2/N
|
||||
.negln2hiN = -0x1.62e42fefa0000p-8,
|
||||
.negln2loN = -0x1.cf79abc9e3b3ap-47,
|
||||
// Used for rounding when !TOINT_INTRINSICS
|
||||
#if EXP_USE_TOINT_NARROW
|
||||
.shift = 0x1800000000.8p0,
|
||||
#else
|
||||
.shift = 0x1.8p52,
|
||||
#endif
|
||||
// exp polynomial coefficients.
|
||||
.poly = {
|
||||
// abs error: 1.555*2^-66
|
||||
// ulp error: 0.509 (0.511 without fma)
|
||||
// if |x| < ln2/256+eps
|
||||
// abs error if |x| < ln2/256+0x1p-15: 1.09*2^-65
|
||||
// abs error if |x| < ln2/128: 1.7145*2^-56
|
||||
0x1.ffffffffffdbdp-2,
|
||||
0x1.555555555543cp-3,
|
||||
0x1.55555cf172b91p-5,
|
||||
0x1.1111167a4d017p-7,
|
||||
},
|
||||
.exp2_shift = 0x1.8p52 / N,
|
||||
// exp2 polynomial coefficients.
|
||||
.exp2_poly = {
|
||||
// abs error: 1.2195*2^-65
|
||||
// ulp error: 0.507 (0.511 without fma)
|
||||
// if |x| < 1/256
|
||||
// abs error if |x| < 1/128: 1.9941*2^-56
|
||||
0x1.62e42fefa39efp-1,
|
||||
0x1.ebfbdff82c424p-3,
|
||||
0x1.c6b08d70cf4b5p-5,
|
||||
0x1.3b2abd24650ccp-7,
|
||||
0x1.5d7e09b4e3a84p-10,
|
||||
},
|
||||
// 2^(k/N) ~= H[k]*(1 + T[k]) for int k in [0,N)
|
||||
// tab[2*k] = asuint64(T[k])
|
||||
// tab[2*k+1] = asuint64(H[k]) - (k << 52)/N
|
||||
.tab = {
|
||||
0x0, 0x3ff0000000000000,
|
||||
0x3c9b3b4f1a88bf6e, 0x3feff63da9fb3335,
|
||||
0xbc7160139cd8dc5d, 0x3fefec9a3e778061,
|
||||
0xbc905e7a108766d1, 0x3fefe315e86e7f85,
|
||||
0x3c8cd2523567f613, 0x3fefd9b0d3158574,
|
||||
0xbc8bce8023f98efa, 0x3fefd06b29ddf6de,
|
||||
0x3c60f74e61e6c861, 0x3fefc74518759bc8,
|
||||
0x3c90a3e45b33d399, 0x3fefbe3ecac6f383,
|
||||
0x3c979aa65d837b6d, 0x3fefb5586cf9890f,
|
||||
0x3c8eb51a92fdeffc, 0x3fefac922b7247f7,
|
||||
0x3c3ebe3d702f9cd1, 0x3fefa3ec32d3d1a2,
|
||||
0xbc6a033489906e0b, 0x3fef9b66affed31b,
|
||||
0xbc9556522a2fbd0e, 0x3fef9301d0125b51,
|
||||
0xbc5080ef8c4eea55, 0x3fef8abdc06c31cc,
|
||||
0xbc91c923b9d5f416, 0x3fef829aaea92de0,
|
||||
0x3c80d3e3e95c55af, 0x3fef7a98c8a58e51,
|
||||
0xbc801b15eaa59348, 0x3fef72b83c7d517b,
|
||||
0xbc8f1ff055de323d, 0x3fef6af9388c8dea,
|
||||
0x3c8b898c3f1353bf, 0x3fef635beb6fcb75,
|
||||
0xbc96d99c7611eb26, 0x3fef5be084045cd4,
|
||||
0x3c9aecf73e3a2f60, 0x3fef54873168b9aa,
|
||||
0xbc8fe782cb86389d, 0x3fef4d5022fcd91d,
|
||||
0x3c8a6f4144a6c38d, 0x3fef463b88628cd6,
|
||||
0x3c807a05b0e4047d, 0x3fef3f49917ddc96,
|
||||
0x3c968efde3a8a894, 0x3fef387a6e756238,
|
||||
0x3c875e18f274487d, 0x3fef31ce4fb2a63f,
|
||||
0x3c80472b981fe7f2, 0x3fef2b4565e27cdd,
|
||||
0xbc96b87b3f71085e, 0x3fef24dfe1f56381,
|
||||
0x3c82f7e16d09ab31, 0x3fef1e9df51fdee1,
|
||||
0xbc3d219b1a6fbffa, 0x3fef187fd0dad990,
|
||||
0x3c8b3782720c0ab4, 0x3fef1285a6e4030b,
|
||||
0x3c6e149289cecb8f, 0x3fef0cafa93e2f56,
|
||||
0x3c834d754db0abb6, 0x3fef06fe0a31b715,
|
||||
0x3c864201e2ac744c, 0x3fef0170fc4cd831,
|
||||
0x3c8fdd395dd3f84a, 0x3feefc08b26416ff,
|
||||
0xbc86a3803b8e5b04, 0x3feef6c55f929ff1,
|
||||
0xbc924aedcc4b5068, 0x3feef1a7373aa9cb,
|
||||
0xbc9907f81b512d8e, 0x3feeecae6d05d866,
|
||||
0xbc71d1e83e9436d2, 0x3feee7db34e59ff7,
|
||||
0xbc991919b3ce1b15, 0x3feee32dc313a8e5,
|
||||
0x3c859f48a72a4c6d, 0x3feedea64c123422,
|
||||
0xbc9312607a28698a, 0x3feeda4504ac801c,
|
||||
0xbc58a78f4817895b, 0x3feed60a21f72e2a,
|
||||
0xbc7c2c9b67499a1b, 0x3feed1f5d950a897,
|
||||
0x3c4363ed60c2ac11, 0x3feece086061892d,
|
||||
0x3c9666093b0664ef, 0x3feeca41ed1d0057,
|
||||
0x3c6ecce1daa10379, 0x3feec6a2b5c13cd0,
|
||||
0x3c93ff8e3f0f1230, 0x3feec32af0d7d3de,
|
||||
0x3c7690cebb7aafb0, 0x3feebfdad5362a27,
|
||||
0x3c931dbdeb54e077, 0x3feebcb299fddd0d,
|
||||
0xbc8f94340071a38e, 0x3feeb9b2769d2ca7,
|
||||
0xbc87deccdc93a349, 0x3feeb6daa2cf6642,
|
||||
0xbc78dec6bd0f385f, 0x3feeb42b569d4f82,
|
||||
0xbc861246ec7b5cf6, 0x3feeb1a4ca5d920f,
|
||||
0x3c93350518fdd78e, 0x3feeaf4736b527da,
|
||||
0x3c7b98b72f8a9b05, 0x3feead12d497c7fd,
|
||||
0x3c9063e1e21c5409, 0x3feeab07dd485429,
|
||||
0x3c34c7855019c6ea, 0x3feea9268a5946b7,
|
||||
0x3c9432e62b64c035, 0x3feea76f15ad2148,
|
||||
0xbc8ce44a6199769f, 0x3feea5e1b976dc09,
|
||||
0xbc8c33c53bef4da8, 0x3feea47eb03a5585,
|
||||
0xbc845378892be9ae, 0x3feea34634ccc320,
|
||||
0xbc93cedd78565858, 0x3feea23882552225,
|
||||
0x3c5710aa807e1964, 0x3feea155d44ca973,
|
||||
0xbc93b3efbf5e2228, 0x3feea09e667f3bcd,
|
||||
0xbc6a12ad8734b982, 0x3feea012750bdabf,
|
||||
0xbc6367efb86da9ee, 0x3fee9fb23c651a2f,
|
||||
0xbc80dc3d54e08851, 0x3fee9f7df9519484,
|
||||
0xbc781f647e5a3ecf, 0x3fee9f75e8ec5f74,
|
||||
0xbc86ee4ac08b7db0, 0x3fee9f9a48a58174,
|
||||
0xbc8619321e55e68a, 0x3fee9feb564267c9,
|
||||
0x3c909ccb5e09d4d3, 0x3feea0694fde5d3f,
|
||||
0xbc7b32dcb94da51d, 0x3feea11473eb0187,
|
||||
0x3c94ecfd5467c06b, 0x3feea1ed0130c132,
|
||||
0x3c65ebe1abd66c55, 0x3feea2f336cf4e62,
|
||||
0xbc88a1c52fb3cf42, 0x3feea427543e1a12,
|
||||
0xbc9369b6f13b3734, 0x3feea589994cce13,
|
||||
0xbc805e843a19ff1e, 0x3feea71a4623c7ad,
|
||||
0xbc94d450d872576e, 0x3feea8d99b4492ed,
|
||||
0x3c90ad675b0e8a00, 0x3feeaac7d98a6699,
|
||||
0x3c8db72fc1f0eab4, 0x3feeace5422aa0db,
|
||||
0xbc65b6609cc5e7ff, 0x3feeaf3216b5448c,
|
||||
0x3c7bf68359f35f44, 0x3feeb1ae99157736,
|
||||
0xbc93091fa71e3d83, 0x3feeb45b0b91ffc6,
|
||||
0xbc5da9b88b6c1e29, 0x3feeb737b0cdc5e5,
|
||||
0xbc6c23f97c90b959, 0x3feeba44cbc8520f,
|
||||
0xbc92434322f4f9aa, 0x3feebd829fde4e50,
|
||||
0xbc85ca6cd7668e4b, 0x3feec0f170ca07ba,
|
||||
0x3c71affc2b91ce27, 0x3feec49182a3f090,
|
||||
0x3c6dd235e10a73bb, 0x3feec86319e32323,
|
||||
0xbc87c50422622263, 0x3feecc667b5de565,
|
||||
0x3c8b1c86e3e231d5, 0x3feed09bec4a2d33,
|
||||
0xbc91bbd1d3bcbb15, 0x3feed503b23e255d,
|
||||
0x3c90cc319cee31d2, 0x3feed99e1330b358,
|
||||
0x3c8469846e735ab3, 0x3feede6b5579fdbf,
|
||||
0xbc82dfcd978e9db4, 0x3feee36bbfd3f37a,
|
||||
0x3c8c1a7792cb3387, 0x3feee89f995ad3ad,
|
||||
0xbc907b8f4ad1d9fa, 0x3feeee07298db666,
|
||||
0xbc55c3d956dcaeba, 0x3feef3a2b84f15fb,
|
||||
0xbc90a40e3da6f640, 0x3feef9728de5593a,
|
||||
0xbc68d6f438ad9334, 0x3feeff76f2fb5e47,
|
||||
0xbc91eee26b588a35, 0x3fef05b030a1064a,
|
||||
0x3c74ffd70a5fddcd, 0x3fef0c1e904bc1d2,
|
||||
0xbc91bdfbfa9298ac, 0x3fef12c25bd71e09,
|
||||
0x3c736eae30af0cb3, 0x3fef199bdd85529c,
|
||||
0x3c8ee3325c9ffd94, 0x3fef20ab5fffd07a,
|
||||
0x3c84e08fd10959ac, 0x3fef27f12e57d14b,
|
||||
0x3c63cdaf384e1a67, 0x3fef2f6d9406e7b5,
|
||||
0x3c676b2c6c921968, 0x3fef3720dcef9069,
|
||||
0xbc808a1883ccb5d2, 0x3fef3f0b555dc3fa,
|
||||
0xbc8fad5d3ffffa6f, 0x3fef472d4a07897c,
|
||||
0xbc900dae3875a949, 0x3fef4f87080d89f2,
|
||||
0x3c74a385a63d07a7, 0x3fef5818dcfba487,
|
||||
0xbc82919e2040220f, 0x3fef60e316c98398,
|
||||
0x3c8e5a50d5c192ac, 0x3fef69e603db3285,
|
||||
0x3c843a59ac016b4b, 0x3fef7321f301b460,
|
||||
0xbc82d52107b43e1f, 0x3fef7c97337b9b5f,
|
||||
0xbc892ab93b470dc9, 0x3fef864614f5a129,
|
||||
0x3c74b604603a88d3, 0x3fef902ee78b3ff6,
|
||||
0x3c83c5ec519d7271, 0x3fef9a51fbc74c83,
|
||||
0xbc8ff7128fd391f0, 0x3fefa4afa2a490da,
|
||||
0xbc8dae98e223747d, 0x3fefaf482d8e67f1,
|
||||
0x3c8ec3bc41aa2008, 0x3fefba1bee615a27,
|
||||
0x3c842b94c3a9eb32, 0x3fefc52b376bba97,
|
||||
0x3c8a64a931d185ee, 0x3fefd0765b6e4540,
|
||||
0xbc8e37bae43be3ed, 0x3fefdbfdad9cbe14,
|
||||
0x3c77893b4d91cd9d, 0x3fefe7c1819e90d8,
|
||||
0x3c5305c14160cc89, 0x3feff3c22b8f71f1,
|
||||
},
|
||||
};
|
25
libc/tinymath/exp_data.internal.h
Normal file
25
libc/tinymath/exp_data.internal.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_EXP_DATA_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_EXP_DATA_H_
|
||||
|
||||
#define EXP_TABLE_BITS 7
|
||||
#define EXP_POLY_ORDER 5
|
||||
#define EXP_USE_TOINT_NARROW 0
|
||||
#define EXP2_POLY_ORDER 5
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct exp_data {
|
||||
double invln2N;
|
||||
double shift;
|
||||
double negln2hiN;
|
||||
double negln2loN;
|
||||
double poly[4]; /* Last four coefficients. */
|
||||
double exp2_shift;
|
||||
double exp2_poly[EXP2_POLY_ORDER];
|
||||
uint64_t tab[2 * (1 << EXP_TABLE_BITS)];
|
||||
} __exp_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_EXP_DATA_H_ */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns 𝑒^x.
|
||||
//
|
||||
|
@ -25,3 +26,5 @@
|
|||
expf: ezlea expl,ax
|
||||
jmp _f2ld2
|
||||
.endfn expf,globl
|
||||
|
||||
#endif /* TINY */
|
119
libc/tinymath/expf.c
Normal file
119
libc/tinymath/expf.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/exp2f_data.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Single-precision e^x function.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
EXP2F_TABLE_BITS = 5
|
||||
EXP2F_POLY_ORDER = 3
|
||||
|
||||
ULP error: 0.502 (nearest rounding.)
|
||||
Relative error: 1.69 * 2^-34 in [-ln2/64, ln2/64] (before rounding.)
|
||||
Wrong count: 170635 (all nearest rounding wrong results with fma.)
|
||||
Non-nearest ULP error: 1 (rounded ULP error)
|
||||
*/
|
||||
|
||||
#define N (1 << EXP2F_TABLE_BITS)
|
||||
#define InvLn2N __exp2f_data.invln2_scaled
|
||||
#define T __exp2f_data.tab
|
||||
#define C __exp2f_data.poly_scaled
|
||||
|
||||
static inline uint32_t top12(float x)
|
||||
{
|
||||
return asuint(x) >> 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 𝑒^x.
|
||||
*/
|
||||
float expf(float x)
|
||||
{
|
||||
uint32_t abstop;
|
||||
uint64_t ki, t;
|
||||
double_t kd, xd, z, r, r2, y, s;
|
||||
|
||||
xd = (double_t)x;
|
||||
abstop = top12(x) & 0x7ff;
|
||||
if (UNLIKELY(abstop >= top12(88.0f))) {
|
||||
/* |x| >= 88 or x is nan. */
|
||||
if (asuint(x) == asuint(-INFINITY))
|
||||
return 0.0f;
|
||||
if (abstop >= top12(INFINITY))
|
||||
return x + x;
|
||||
if (x > 0x1.62e42ep6f) /* x > log(0x1p128) ~= 88.72 */
|
||||
return __math_oflowf(0);
|
||||
if (x < -0x1.9fe368p6f) /* x < log(0x1p-150) ~= -103.97 */
|
||||
return __math_uflowf(0);
|
||||
}
|
||||
|
||||
/* x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k. */
|
||||
z = InvLn2N * xd;
|
||||
|
||||
/* Round and convert z to int, the result is in [-150*N, 128*N] and
|
||||
ideally ties-to-even rule is used, otherwise the magnitude of r
|
||||
can be bigger which gives larger approximation error. */
|
||||
#if TOINT_INTRINSICS
|
||||
kd = roundtoint(z);
|
||||
ki = converttoint(z);
|
||||
#else
|
||||
# define SHIFT __exp2f_data.shift
|
||||
kd = eval_as_double(z + SHIFT);
|
||||
ki = asuint64(kd);
|
||||
kd -= SHIFT;
|
||||
#endif
|
||||
r = z - kd;
|
||||
|
||||
/* exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */
|
||||
t = T[ki % N];
|
||||
t += ki << (52 - EXP2F_TABLE_BITS);
|
||||
s = asdouble(t);
|
||||
z = C[0] * r + C[1];
|
||||
r2 = r * r;
|
||||
y = C[2] * r + 1;
|
||||
y = z * r2 + y;
|
||||
y = y * s;
|
||||
return eval_as_float(y);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
78
libc/tinymath/internal.h
Normal file
78
libc/tinymath/internal.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_INTERNAL_H_
|
||||
|
||||
#define WANT_ROUNDING 1
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define issignalingf_inline(x) 0
|
||||
#define issignaling_inline(x) 0
|
||||
|
||||
// clang-format off
|
||||
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
|
||||
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
|
||||
#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
|
||||
#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
|
||||
// clang-format on
|
||||
|
||||
static inline float eval_as_float(float x) {
|
||||
float y = x;
|
||||
return y;
|
||||
}
|
||||
|
||||
static inline double eval_as_double(double x) {
|
||||
double y = x;
|
||||
return y;
|
||||
}
|
||||
|
||||
static inline void fp_force_evall(long double x) {
|
||||
volatile long double y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
static inline void fp_force_evalf(float x) {
|
||||
volatile float y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
static inline void fp_force_eval(double x) {
|
||||
volatile double y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
static inline double fp_barrier(double x) {
|
||||
volatile double y = x;
|
||||
return y;
|
||||
}
|
||||
|
||||
static inline float fp_barrierf(float x) {
|
||||
volatile float y = x;
|
||||
return y;
|
||||
}
|
||||
|
||||
double __math_divzero(uint32_t) hidden;
|
||||
double __math_invalid(double) hidden;
|
||||
double __math_oflow(uint32_t) hidden;
|
||||
double __math_uflow(uint32_t) hidden;
|
||||
double __math_xflow(uint32_t, double) hidden;
|
||||
float __math_divzerof(uint32_t) hidden;
|
||||
float __math_invalidf(float) hidden;
|
||||
float __math_oflowf(uint32_t) hidden;
|
||||
float __math_uflowf(uint32_t) hidden;
|
||||
float __math_xflowf(uint32_t, float) hidden;
|
||||
|
||||
#define FORCE_EVAL(x) \
|
||||
do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
fp_force_evalf(x); \
|
||||
} else if (sizeof(x) == sizeof(double)) { \
|
||||
fp_force_eval(x); \
|
||||
} else { \
|
||||
fp_force_evall(x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_INTERNAL_H_ */
|
|
@ -5,14 +5,14 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
extern int __signgam;
|
||||
|
||||
float __cosdf(double);
|
||||
float __sindf(double);
|
||||
float __tandf(double, int);
|
||||
double __sin(double, double, int);
|
||||
double __tan(double, double, int);
|
||||
double __cos(double, double);
|
||||
int __rem_pio2(double, double *);
|
||||
int __rem_pio2_large(double *, double *, int, int, int);
|
||||
float __cosdf(double) hidden;
|
||||
float __sindf(double) hidden;
|
||||
float __tandf(double, int) hidden;
|
||||
double __sin(double, double, int) hidden;
|
||||
double __tan(double, double, int) hidden;
|
||||
double __cos(double, double) hidden;
|
||||
int __rem_pio2(double, double *) hidden;
|
||||
int __rem_pio2_large(double *, double *, int, int, int) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns natural logarithm of 𝑥.
|
||||
//
|
||||
|
@ -25,3 +26,5 @@
|
|||
log: ezlea logl,ax
|
||||
jmp _d2ld2
|
||||
.endfn log,globl
|
||||
|
||||
#endif /* TINY */
|
151
libc/tinymath/log.c
Normal file
151
libc/tinymath/log.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#include "libc/tinymath/log_data.internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Double-precision log(x) function.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define T __log_data.tab
|
||||
#define T2 __log_data.tab2
|
||||
#define B __log_data.poly1
|
||||
#define A __log_data.poly
|
||||
#define Ln2hi __log_data.ln2hi
|
||||
#define Ln2lo __log_data.ln2lo
|
||||
#define N (1 << LOG_TABLE_BITS)
|
||||
#define OFF 0x3fe6000000000000
|
||||
|
||||
/* Top 16 bits of a double. */
|
||||
static inline uint32_t top16(double x)
|
||||
{
|
||||
return asuint64(x) >> 48;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns natural logarithm of 𝑥.
|
||||
*/
|
||||
double log(double x)
|
||||
{
|
||||
double_t w, z, r, r2, r3, y, invc, logc, kd, hi, lo;
|
||||
uint64_t ix, iz, tmp;
|
||||
uint32_t top;
|
||||
int k, i;
|
||||
|
||||
ix = asuint64(x);
|
||||
top = top16(x);
|
||||
#define LO asuint64(1.0 - 0x1p-4)
|
||||
#define HI asuint64(1.0 + 0x1.09p-4)
|
||||
if (UNLIKELY(ix - LO < HI - LO)) {
|
||||
/* Handle close to 1.0 inputs separately. */
|
||||
/* Fix sign of zero with downward rounding when x==1. */
|
||||
if (WANT_ROUNDING && UNLIKELY(ix == asuint64(1.0)))
|
||||
return 0;
|
||||
r = x - 1.0;
|
||||
r2 = r * r;
|
||||
r3 = r * r2;
|
||||
y = r3 *
|
||||
(B[1] + r * B[2] + r2 * B[3] +
|
||||
r3 * (B[4] + r * B[5] + r2 * B[6] +
|
||||
r3 * (B[7] + r * B[8] + r2 * B[9] + r3 * B[10])));
|
||||
/* Worst-case error is around 0.507 ULP. */
|
||||
w = r * 0x1p27;
|
||||
double_t rhi = r + w - w;
|
||||
double_t rlo = r - rhi;
|
||||
w = rhi * rhi * B[0]; /* B[0] == -0.5. */
|
||||
hi = r + w;
|
||||
lo = r - hi + w;
|
||||
lo += B[0] * rlo * (rhi + r);
|
||||
y += lo;
|
||||
y += hi;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
if (UNLIKELY(top - 0x0010 >= 0x7ff0 - 0x0010)) {
|
||||
/* x < 0x1p-1022 or inf or nan. */
|
||||
if (ix * 2 == 0)
|
||||
return __math_divzero(1);
|
||||
if (ix == asuint64(INFINITY)) /* log(inf) == inf. */
|
||||
return x;
|
||||
if ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)
|
||||
return __math_invalid(x);
|
||||
/* x is subnormal, normalize it. */
|
||||
ix = asuint64(x * 0x1p52);
|
||||
ix -= 52ULL << 52;
|
||||
}
|
||||
|
||||
/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
|
||||
The range is split into N subintervals.
|
||||
The ith subinterval contains z and c is near its center. */
|
||||
tmp = ix - OFF;
|
||||
i = (tmp >> (52 - LOG_TABLE_BITS)) % N;
|
||||
k = (int64_t)tmp >> 52; /* arithmetic shift */
|
||||
iz = ix - (tmp & 0xfffULL << 52);
|
||||
invc = T[i].invc;
|
||||
logc = T[i].logc;
|
||||
z = asdouble(iz);
|
||||
|
||||
/* log(x) = log1p(z/c-1) + log(c) + k*Ln2. */
|
||||
/* r ~= z/c - 1, |r| < 1/(2*N). */
|
||||
#if __FP_FAST_FMA
|
||||
/* rounding error: 0x1p-55/N. */
|
||||
r = __builtin_fma(z, invc, -1.0);
|
||||
#else
|
||||
/* rounding error: 0x1p-55/N + 0x1p-66. */
|
||||
r = (z - T2[i].chi - T2[i].clo) * invc;
|
||||
#endif
|
||||
kd = (double_t)k;
|
||||
|
||||
/* hi + lo = r + log(c) + k*Ln2. */
|
||||
w = kd * Ln2hi + logc;
|
||||
hi = w + r;
|
||||
lo = w - hi + r + kd * Ln2lo;
|
||||
|
||||
/* log(x) = lo + (log1p(r) - r) + hi. */
|
||||
r2 = r * r; /* rounding error: 0x1p-54/N^2. */
|
||||
/* Worst case error if |y| > 0x1p-5:
|
||||
0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)
|
||||
Worst case error if |y| > 0x1p-4:
|
||||
0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma). */
|
||||
y = lo + r2 * A[0] +
|
||||
r * r2 * (A[1] + r * A[2] + r2 * (A[3] + r * A[4])) + hi;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Calculates log₁₀𝑥.
|
||||
//
|
||||
|
@ -25,3 +26,5 @@
|
|||
log10: ezlea log10l,ax
|
||||
jmp _d2ld2
|
||||
.endfn log10,globl
|
||||
|
||||
#endif /* TINY */
|
146
libc/tinymath/log10.c
Normal file
146
libc/tinymath/log10.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/complex.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#include "libc/tinymath/log2_data.internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
fdlibm (fdlibm license)\\n\
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/*
|
||||
* Return the base 10 logarithm of x. See log.c for most comments.
|
||||
*
|
||||
* Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
|
||||
* as in log.c, then combine and scale in extra precision:
|
||||
* log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2)
|
||||
*/
|
||||
|
||||
static const double
|
||||
ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */
|
||||
ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */
|
||||
log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
|
||||
log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */
|
||||
Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
|
||||
Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
|
||||
Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
|
||||
Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
|
||||
Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
|
||||
Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
|
||||
Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
|
||||
|
||||
/**
|
||||
* Calculates log₁₀𝑥.
|
||||
*/
|
||||
double log10(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo;
|
||||
uint32_t hx;
|
||||
int k;
|
||||
|
||||
hx = u.i>>32;
|
||||
k = 0;
|
||||
if (hx < 0x00100000 || hx>>31) {
|
||||
if (u.i<<1 == 0)
|
||||
return -1/(x*x); /* log(+-0)=-inf */
|
||||
if (hx>>31)
|
||||
return (x-x)/0.0; /* log(-#) = NaN */
|
||||
/* subnormal number, scale x up */
|
||||
k -= 54;
|
||||
x *= 0x1p54;
|
||||
u.f = x;
|
||||
hx = u.i>>32;
|
||||
} else if (hx >= 0x7ff00000) {
|
||||
return x;
|
||||
} else if (hx == 0x3ff00000 && u.i<<32 == 0)
|
||||
return 0;
|
||||
|
||||
/* reduce x into [sqrt(2)/2, sqrt(2)] */
|
||||
hx += 0x3ff00000 - 0x3fe6a09e;
|
||||
k += (int)(hx>>20) - 0x3ff;
|
||||
hx = (hx&0x000fffff) + 0x3fe6a09e;
|
||||
u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
|
||||
x = u.f;
|
||||
|
||||
f = x - 1.0;
|
||||
hfsq = 0.5*f*f;
|
||||
s = f/(2.0+f);
|
||||
z = s*s;
|
||||
w = z*z;
|
||||
t1 = w*(Lg2+w*(Lg4+w*Lg6));
|
||||
t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
|
||||
R = t2 + t1;
|
||||
|
||||
/* See log2.c for details. */
|
||||
/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
|
||||
hi = f - hfsq;
|
||||
u.f = hi;
|
||||
u.i &= (uint64_t)-1<<32;
|
||||
hi = u.f;
|
||||
lo = f - hi - hfsq + s*(hfsq+R);
|
||||
|
||||
/* val_hi+val_lo ~ log10(1+f) + k*log10(2) */
|
||||
val_hi = hi*ivln10hi;
|
||||
dk = k;
|
||||
y = dk*log10_2hi;
|
||||
val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;
|
||||
|
||||
/*
|
||||
* Extra precision in for adding y is not strictly needed
|
||||
* since there is no very large cancellation near x = sqrt(2) or
|
||||
* x = 1/sqrt(2), but we do it anyway since it costs little on CPUs
|
||||
* with some parallelism and it reduces the error for many args.
|
||||
*/
|
||||
w = y + val_hi;
|
||||
val_lo += (y - w) + val_hi;
|
||||
val_hi = w;
|
||||
|
||||
return val_lo + val_hi;
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Calculates log₂𝑥.
|
||||
//
|
||||
|
@ -35,3 +36,5 @@ log2: push %rbp
|
|||
leave
|
||||
ret
|
||||
.endfn log2,globl
|
||||
|
||||
#endif /* TINY */
|
162
libc/tinymath/log2.c
Normal file
162
libc/tinymath/log2.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/complex.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#include "libc/tinymath/log2_data.internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Double-precision log2(x) function.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define T __log2_data.tab
|
||||
#define T2 __log2_data.tab2
|
||||
#define B __log2_data.poly1
|
||||
#define A __log2_data.poly
|
||||
#define InvLn2hi __log2_data.invln2hi
|
||||
#define InvLn2lo __log2_data.invln2lo
|
||||
#define N (1 << LOG2_TABLE_BITS)
|
||||
#define OFF 0x3fe6000000000000
|
||||
|
||||
/* Top 16 bits of a double. */
|
||||
static inline uint32_t top16(double x)
|
||||
{
|
||||
return asuint64(x) >> 48;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates log₂𝑥.
|
||||
*/
|
||||
double log2(double x)
|
||||
{
|
||||
double_t z, r, r2, r4, y, invc, logc, kd, hi, lo, t1, t2, t3, p;
|
||||
uint64_t ix, iz, tmp;
|
||||
uint32_t top;
|
||||
int k, i;
|
||||
|
||||
ix = asuint64(x);
|
||||
top = top16(x);
|
||||
#define LO asuint64(1.0 - 0x1.5b51p-5)
|
||||
#define HI asuint64(1.0 + 0x1.6ab2p-5)
|
||||
if (UNLIKELY(ix - LO < HI - LO)) {
|
||||
/* Handle close to 1.0 inputs separately. */
|
||||
/* Fix sign of zero with downward rounding when x==1. */
|
||||
if (WANT_ROUNDING && UNLIKELY(ix == asuint64(1.0)))
|
||||
return 0;
|
||||
r = x - 1.0;
|
||||
#if __FP_FAST_FMA
|
||||
hi = r * InvLn2hi;
|
||||
lo = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -hi);
|
||||
#else
|
||||
double_t rhi, rlo;
|
||||
rhi = asdouble(asuint64(r) & -1ULL << 32);
|
||||
rlo = r - rhi;
|
||||
hi = rhi * InvLn2hi;
|
||||
lo = rlo * InvLn2hi + r * InvLn2lo;
|
||||
#endif
|
||||
r2 = r * r; /* rounding error: 0x1p-62. */
|
||||
r4 = r2 * r2;
|
||||
/* Worst-case error is less than 0.54 ULP (0.55 ULP without fma). */
|
||||
p = r2 * (B[0] + r * B[1]);
|
||||
y = hi + p;
|
||||
lo += hi - y + p;
|
||||
lo += r4 * (B[2] + r * B[3] + r2 * (B[4] + r * B[5]) +
|
||||
r4 * (B[6] + r * B[7] + r2 * (B[8] + r * B[9])));
|
||||
y += lo;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
if (UNLIKELY(top - 0x0010 >= 0x7ff0 - 0x0010)) {
|
||||
/* x < 0x1p-1022 or inf or nan. */
|
||||
if (ix * 2 == 0)
|
||||
return __math_divzero(1);
|
||||
if (ix == asuint64(INFINITY)) /* log(inf) == inf. */
|
||||
return x;
|
||||
if ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)
|
||||
return __math_invalid(x);
|
||||
/* x is subnormal, normalize it. */
|
||||
ix = asuint64(x * 0x1p52);
|
||||
ix -= 52ULL << 52;
|
||||
}
|
||||
|
||||
/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
|
||||
The range is split into N subintervals.
|
||||
The ith subinterval contains z and c is near its center. */
|
||||
tmp = ix - OFF;
|
||||
i = (tmp >> (52 - LOG2_TABLE_BITS)) % N;
|
||||
k = (int64_t)tmp >> 52; /* arithmetic shift */
|
||||
iz = ix - (tmp & 0xfffULL << 52);
|
||||
invc = T[i].invc;
|
||||
logc = T[i].logc;
|
||||
z = asdouble(iz);
|
||||
kd = (double_t)k;
|
||||
|
||||
/* log2(x) = log2(z/c) + log2(c) + k. */
|
||||
/* r ~= z/c - 1, |r| < 1/(2*N). */
|
||||
#if __FP_FAST_FMA
|
||||
/* rounding error: 0x1p-55/N. */
|
||||
r = __builtin_fma(z, invc, -1.0);
|
||||
t1 = r * InvLn2hi;
|
||||
t2 = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -t1);
|
||||
#else
|
||||
double_t rhi, rlo;
|
||||
/* rounding error: 0x1p-55/N + 0x1p-65. */
|
||||
r = (z - T2[i].chi - T2[i].clo) * invc;
|
||||
rhi = asdouble(asuint64(r) & -1ULL << 32);
|
||||
rlo = r - rhi;
|
||||
t1 = rhi * InvLn2hi;
|
||||
t2 = rlo * InvLn2hi + r * InvLn2lo;
|
||||
#endif
|
||||
|
||||
/* hi + lo = r/ln2 + log2(c) + k. */
|
||||
t3 = kd + logc;
|
||||
hi = t3 + t1;
|
||||
lo = t3 - hi + t1 + t2;
|
||||
|
||||
/* log2(r+1) = r/ln2 + r^2*poly(r). */
|
||||
/* Evaluation is optimized assuming superscalar pipelined execution. */
|
||||
r2 = r * r; /* rounding error: 0x1p-54/N^2. */
|
||||
r4 = r2 * r2;
|
||||
/* Worst-case error if |y| > 0x1p-4: 0.547 ULP (0.550 ULP without fma).
|
||||
~ 0.5 + 2/N/ln2 + abs-poly-error*0x1p56 ULP (+ 0.003 ULP without fma). */
|
||||
p = A[0] + r * A[1] + r2 * (A[2] + r * A[3]) + r4 * (A[4] + r * A[5]);
|
||||
y = lo + r2 * p + hi;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
234
libc/tinymath/log2_data.c
Normal file
234
libc/tinymath/log2_data.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/log2_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Data for log2.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << LOG2_TABLE_BITS)
|
||||
|
||||
const struct log2_data __log2_data = {
|
||||
// First coefficient: 0x1.71547652b82fe1777d0ffda0d24p0
|
||||
.invln2hi = 0x1.7154765200000p+0,
|
||||
.invln2lo = 0x1.705fc2eefa200p-33,
|
||||
.poly1 = {
|
||||
// relative error: 0x1.2fad8188p-63
|
||||
// in -0x1.5b51p-5 0x1.6ab2p-5
|
||||
-0x1.71547652b82fep-1,
|
||||
0x1.ec709dc3a03f7p-2,
|
||||
-0x1.71547652b7c3fp-2,
|
||||
0x1.2776c50f05be4p-2,
|
||||
-0x1.ec709dd768fe5p-3,
|
||||
0x1.a61761ec4e736p-3,
|
||||
-0x1.7153fbc64a79bp-3,
|
||||
0x1.484d154f01b4ap-3,
|
||||
-0x1.289e4a72c383cp-3,
|
||||
0x1.0b32f285aee66p-3,
|
||||
},
|
||||
.poly = {
|
||||
// relative error: 0x1.a72c2bf8p-58
|
||||
// abs error: 0x1.67a552c8p-66
|
||||
// in -0x1.f45p-8 0x1.f45p-8
|
||||
-0x1.71547652b8339p-1,
|
||||
0x1.ec709dc3a04bep-2,
|
||||
-0x1.7154764702ffbp-2,
|
||||
0x1.2776c50034c48p-2,
|
||||
-0x1.ec7b328ea92bcp-3,
|
||||
0x1.a6225e117f92ep-3,
|
||||
},
|
||||
/* Algorithm:
|
||||
|
||||
x = 2^k z
|
||||
log2(x) = k + log2(c) + log2(z/c)
|
||||
log2(z/c) = poly(z/c - 1)
|
||||
|
||||
where z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls
|
||||
into the ith one, then table entries are computed as
|
||||
|
||||
tab[i].invc = 1/c
|
||||
tab[i].logc = (double)log2(c)
|
||||
tab2[i].chi = (double)c
|
||||
tab2[i].clo = (double)(c - (double)c)
|
||||
|
||||
where c is near the center of the subinterval and is chosen by trying +-2^29
|
||||
floating point invc candidates around 1/center and selecting one for which
|
||||
|
||||
1) the rounding error in 0x1.8p10 + logc is 0,
|
||||
2) the rounding error in z - chi - clo is < 0x1p-64 and
|
||||
3) the rounding error in (double)log2(c) is minimized (< 0x1p-68).
|
||||
|
||||
Note: 1) ensures that k + logc can be computed without rounding error, 2)
|
||||
ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to a
|
||||
single rounding error when there is no fast fma for z*invc - 1, 3) ensures
|
||||
that logc + poly(z/c - 1) has small error, however near x == 1 when
|
||||
|log2(x)| < 0x1p-4, this is not enough so that is special cased. */
|
||||
.tab = {
|
||||
{0x1.724286bb1acf8p+0, -0x1.1095feecdb000p-1},
|
||||
{0x1.6e1f766d2cca1p+0, -0x1.08494bd76d000p-1},
|
||||
{0x1.6a13d0e30d48ap+0, -0x1.00143aee8f800p-1},
|
||||
{0x1.661ec32d06c85p+0, -0x1.efec5360b4000p-2},
|
||||
{0x1.623fa951198f8p+0, -0x1.dfdd91ab7e000p-2},
|
||||
{0x1.5e75ba4cf026cp+0, -0x1.cffae0cc79000p-2},
|
||||
{0x1.5ac055a214fb8p+0, -0x1.c043811fda000p-2},
|
||||
{0x1.571ed0f166e1ep+0, -0x1.b0b67323ae000p-2},
|
||||
{0x1.53909590bf835p+0, -0x1.a152f5a2db000p-2},
|
||||
{0x1.5014fed61adddp+0, -0x1.9217f5af86000p-2},
|
||||
{0x1.4cab88e487bd0p+0, -0x1.8304db0719000p-2},
|
||||
{0x1.49539b4334feep+0, -0x1.74189f9a9e000p-2},
|
||||
{0x1.460cbdfafd569p+0, -0x1.6552bb5199000p-2},
|
||||
{0x1.42d664ee4b953p+0, -0x1.56b23a29b1000p-2},
|
||||
{0x1.3fb01111dd8a6p+0, -0x1.483650f5fa000p-2},
|
||||
{0x1.3c995b70c5836p+0, -0x1.39de937f6a000p-2},
|
||||
{0x1.3991c4ab6fd4ap+0, -0x1.2baa1538d6000p-2},
|
||||
{0x1.3698e0ce099b5p+0, -0x1.1d98340ca4000p-2},
|
||||
{0x1.33ae48213e7b2p+0, -0x1.0fa853a40e000p-2},
|
||||
{0x1.30d191985bdb1p+0, -0x1.01d9c32e73000p-2},
|
||||
{0x1.2e025cab271d7p+0, -0x1.e857da2fa6000p-3},
|
||||
{0x1.2b404cf13cd82p+0, -0x1.cd3c8633d8000p-3},
|
||||
{0x1.288b02c7ccb50p+0, -0x1.b26034c14a000p-3},
|
||||
{0x1.25e2263944de5p+0, -0x1.97c1c2f4fe000p-3},
|
||||
{0x1.234563d8615b1p+0, -0x1.7d6023f800000p-3},
|
||||
{0x1.20b46e33eaf38p+0, -0x1.633a71a05e000p-3},
|
||||
{0x1.1e2eefdcda3ddp+0, -0x1.494f5e9570000p-3},
|
||||
{0x1.1bb4a580b3930p+0, -0x1.2f9e424e0a000p-3},
|
||||
{0x1.19453847f2200p+0, -0x1.162595afdc000p-3},
|
||||
{0x1.16e06c0d5d73cp+0, -0x1.f9c9a75bd8000p-4},
|
||||
{0x1.1485f47b7e4c2p+0, -0x1.c7b575bf9c000p-4},
|
||||
{0x1.12358ad0085d1p+0, -0x1.960c60ff48000p-4},
|
||||
{0x1.0fef00f532227p+0, -0x1.64ce247b60000p-4},
|
||||
{0x1.0db2077d03a8fp+0, -0x1.33f78b2014000p-4},
|
||||
{0x1.0b7e6d65980d9p+0, -0x1.0387d1a42c000p-4},
|
||||
{0x1.0953efe7b408dp+0, -0x1.a6f9208b50000p-5},
|
||||
{0x1.07325cac53b83p+0, -0x1.47a954f770000p-5},
|
||||
{0x1.05197e40d1b5cp+0, -0x1.d23a8c50c0000p-6},
|
||||
{0x1.03091c1208ea2p+0, -0x1.16a2629780000p-6},
|
||||
{0x1.0101025b37e21p+0, -0x1.720f8d8e80000p-8},
|
||||
{0x1.fc07ef9caa76bp-1, 0x1.6fe53b1500000p-7},
|
||||
{0x1.f4465d3f6f184p-1, 0x1.11ccce10f8000p-5},
|
||||
{0x1.ecc079f84107fp-1, 0x1.c4dfc8c8b8000p-5},
|
||||
{0x1.e573a99975ae8p-1, 0x1.3aa321e574000p-4},
|
||||
{0x1.de5d6f0bd3de6p-1, 0x1.918a0d08b8000p-4},
|
||||
{0x1.d77b681ff38b3p-1, 0x1.e72e9da044000p-4},
|
||||
{0x1.d0cb5724de943p-1, 0x1.1dcd2507f6000p-3},
|
||||
{0x1.ca4b2dc0e7563p-1, 0x1.476ab03dea000p-3},
|
||||
{0x1.c3f8ee8d6cb51p-1, 0x1.7074377e22000p-3},
|
||||
{0x1.bdd2b4f020c4cp-1, 0x1.98ede8ba94000p-3},
|
||||
{0x1.b7d6c006015cap-1, 0x1.c0db86ad2e000p-3},
|
||||
{0x1.b20366e2e338fp-1, 0x1.e840aafcee000p-3},
|
||||
{0x1.ac57026295039p-1, 0x1.0790ab4678000p-2},
|
||||
{0x1.a6d01bc2731ddp-1, 0x1.1ac056801c000p-2},
|
||||
{0x1.a16d3bc3ff18bp-1, 0x1.2db11d4fee000p-2},
|
||||
{0x1.9c2d14967feadp-1, 0x1.406464ec58000p-2},
|
||||
{0x1.970e4f47c9902p-1, 0x1.52dbe093af000p-2},
|
||||
{0x1.920fb3982bcf2p-1, 0x1.651902050d000p-2},
|
||||
{0x1.8d30187f759f1p-1, 0x1.771d2cdeaf000p-2},
|
||||
{0x1.886e5ebb9f66dp-1, 0x1.88e9c857d9000p-2},
|
||||
{0x1.83c97b658b994p-1, 0x1.9a80155e16000p-2},
|
||||
{0x1.7f405ffc61022p-1, 0x1.abe186ed3d000p-2},
|
||||
{0x1.7ad22181415cap-1, 0x1.bd0f2aea0e000p-2},
|
||||
{0x1.767dcf99eff8cp-1, 0x1.ce0a43dbf4000p-2},
|
||||
},
|
||||
#if !__FP_FAST_FMA
|
||||
.tab2 = {
|
||||
{0x1.6200012b90a8ep-1, 0x1.904ab0644b605p-55},
|
||||
{0x1.66000045734a6p-1, 0x1.1ff9bea62f7a9p-57},
|
||||
{0x1.69fffc325f2c5p-1, 0x1.27ecfcb3c90bap-55},
|
||||
{0x1.6e00038b95a04p-1, 0x1.8ff8856739326p-55},
|
||||
{0x1.71fffe09994e3p-1, 0x1.afd40275f82b1p-55},
|
||||
{0x1.7600015590e1p-1, -0x1.2fd75b4238341p-56},
|
||||
{0x1.7a00012655bd5p-1, 0x1.808e67c242b76p-56},
|
||||
{0x1.7e0003259e9a6p-1, -0x1.208e426f622b7p-57},
|
||||
{0x1.81fffedb4b2d2p-1, -0x1.402461ea5c92fp-55},
|
||||
{0x1.860002dfafcc3p-1, 0x1.df7f4a2f29a1fp-57},
|
||||
{0x1.89ffff78c6b5p-1, -0x1.e0453094995fdp-55},
|
||||
{0x1.8e00039671566p-1, -0x1.a04f3bec77b45p-55},
|
||||
{0x1.91fffe2bf1745p-1, -0x1.7fa34400e203cp-56},
|
||||
{0x1.95fffcc5c9fd1p-1, -0x1.6ff8005a0695dp-56},
|
||||
{0x1.9a0003bba4767p-1, 0x1.0f8c4c4ec7e03p-56},
|
||||
{0x1.9dfffe7b92da5p-1, 0x1.e7fd9478c4602p-55},
|
||||
{0x1.a1fffd72efdafp-1, -0x1.a0c554dcdae7ep-57},
|
||||
{0x1.a5fffde04ff95p-1, 0x1.67da98ce9b26bp-55},
|
||||
{0x1.a9fffca5e8d2bp-1, -0x1.284c9b54c13dep-55},
|
||||
{0x1.adfffddad03eap-1, 0x1.812c8ea602e3cp-58},
|
||||
{0x1.b1ffff10d3d4dp-1, -0x1.efaddad27789cp-55},
|
||||
{0x1.b5fffce21165ap-1, 0x1.3cb1719c61237p-58},
|
||||
{0x1.b9fffd950e674p-1, 0x1.3f7d94194cep-56},
|
||||
{0x1.be000139ca8afp-1, 0x1.50ac4215d9bcp-56},
|
||||
{0x1.c20005b46df99p-1, 0x1.beea653e9c1c9p-57},
|
||||
{0x1.c600040b9f7aep-1, -0x1.c079f274a70d6p-56},
|
||||
{0x1.ca0006255fd8ap-1, -0x1.a0b4076e84c1fp-56},
|
||||
{0x1.cdfffd94c095dp-1, 0x1.8f933f99ab5d7p-55},
|
||||
{0x1.d1ffff975d6cfp-1, -0x1.82c08665fe1bep-58},
|
||||
{0x1.d5fffa2561c93p-1, -0x1.b04289bd295f3p-56},
|
||||
{0x1.d9fff9d228b0cp-1, 0x1.70251340fa236p-55},
|
||||
{0x1.de00065bc7e16p-1, -0x1.5011e16a4d80cp-56},
|
||||
{0x1.e200002f64791p-1, 0x1.9802f09ef62ep-55},
|
||||
{0x1.e600057d7a6d8p-1, -0x1.e0b75580cf7fap-56},
|
||||
{0x1.ea00027edc00cp-1, -0x1.c848309459811p-55},
|
||||
{0x1.ee0006cf5cb7cp-1, -0x1.f8027951576f4p-55},
|
||||
{0x1.f2000782b7dccp-1, -0x1.f81d97274538fp-55},
|
||||
{0x1.f6000260c450ap-1, -0x1.071002727ffdcp-59},
|
||||
{0x1.f9fffe88cd533p-1, -0x1.81bdce1fda8bp-58},
|
||||
{0x1.fdfffd50f8689p-1, 0x1.7f91acb918e6ep-55},
|
||||
{0x1.0200004292367p+0, 0x1.b7ff365324681p-54},
|
||||
{0x1.05fffe3e3d668p+0, 0x1.6fa08ddae957bp-55},
|
||||
{0x1.0a0000a85a757p+0, -0x1.7e2de80d3fb91p-58},
|
||||
{0x1.0e0001a5f3fccp+0, -0x1.1823305c5f014p-54},
|
||||
{0x1.11ffff8afbaf5p+0, -0x1.bfabb6680bac2p-55},
|
||||
{0x1.15fffe54d91adp+0, -0x1.d7f121737e7efp-54},
|
||||
{0x1.1a00011ac36e1p+0, 0x1.c000a0516f5ffp-54},
|
||||
{0x1.1e00019c84248p+0, -0x1.082fbe4da5dap-54},
|
||||
{0x1.220000ffe5e6ep+0, -0x1.8fdd04c9cfb43p-55},
|
||||
{0x1.26000269fd891p+0, 0x1.cfe2a7994d182p-55},
|
||||
{0x1.2a00029a6e6dap+0, -0x1.00273715e8bc5p-56},
|
||||
{0x1.2dfffe0293e39p+0, 0x1.b7c39dab2a6f9p-54},
|
||||
{0x1.31ffff7dcf082p+0, 0x1.df1336edc5254p-56},
|
||||
{0x1.35ffff05a8b6p+0, -0x1.e03564ccd31ebp-54},
|
||||
{0x1.3a0002e0eaeccp+0, 0x1.5f0e74bd3a477p-56},
|
||||
{0x1.3e000043bb236p+0, 0x1.c7dcb149d8833p-54},
|
||||
{0x1.4200002d187ffp+0, 0x1.e08afcf2d3d28p-56},
|
||||
{0x1.460000d387cb1p+0, 0x1.20837856599a6p-55},
|
||||
{0x1.4a00004569f89p+0, -0x1.9fa5c904fbcd2p-55},
|
||||
{0x1.4e000043543f3p+0, -0x1.81125ed175329p-56},
|
||||
{0x1.51fffcc027f0fp+0, 0x1.883d8847754dcp-54},
|
||||
{0x1.55ffffd87b36fp+0, -0x1.709e731d02807p-55},
|
||||
{0x1.59ffff21df7bap+0, 0x1.7f79f68727b02p-55},
|
||||
{0x1.5dfffebfc3481p+0, -0x1.180902e30e93ep-54},
|
||||
},
|
||||
#endif
|
||||
};
|
28
libc/tinymath/log2_data.internal.h
Normal file
28
libc/tinymath/log2_data.internal.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_LOG2_DATA_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_LOG2_DATA_INTERNAL_H_
|
||||
|
||||
#define LOG2_TABLE_BITS 6
|
||||
#define LOG2_POLY_ORDER 7
|
||||
#define LOG2_POLY1_ORDER 11
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct log2_data {
|
||||
double invln2hi;
|
||||
double invln2lo;
|
||||
double poly[LOG2_POLY_ORDER - 1];
|
||||
double poly1[LOG2_POLY1_ORDER - 1];
|
||||
struct {
|
||||
double invc, logc;
|
||||
} tab[1 << LOG2_TABLE_BITS];
|
||||
#if !__FP_FAST_FMA
|
||||
struct {
|
||||
double chi, clo;
|
||||
} tab2[1 << LOG2_TABLE_BITS];
|
||||
#endif
|
||||
} __log2_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_LOG2_DATA_INTERNAL_H_ */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Calculates log₂𝑥.
|
||||
//
|
||||
|
@ -35,3 +36,5 @@ log2f: push %rbp
|
|||
leave
|
||||
ret
|
||||
.endfn log2f,globl
|
||||
|
||||
#endif /* TINY */
|
112
libc/tinymath/log2f.c
Normal file
112
libc/tinymath/log2f.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/complex.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#include "libc/tinymath/log2f_data.internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Single-precision log2 function.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
LOG2F_TABLE_BITS = 4
|
||||
LOG2F_POLY_ORDER = 4
|
||||
|
||||
ULP error: 0.752 (nearest rounding.)
|
||||
Relative error: 1.9 * 2^-26 (before rounding.)
|
||||
*/
|
||||
|
||||
#define N (1 << LOG2F_TABLE_BITS)
|
||||
#define T __log2f_data.tab
|
||||
#define A __log2f_data.poly
|
||||
#define OFF 0x3f330000
|
||||
|
||||
/**
|
||||
* Calculates log₂𝑥.
|
||||
*/
|
||||
float log2f(float x)
|
||||
{
|
||||
double_t z, r, r2, p, y, y0, invc, logc;
|
||||
uint32_t ix, iz, top, tmp;
|
||||
int k, i;
|
||||
|
||||
ix = asuint(x);
|
||||
/* Fix sign of zero with downward rounding when x==1. */
|
||||
if (WANT_ROUNDING && UNLIKELY(ix == 0x3f800000))
|
||||
return 0;
|
||||
if (UNLIKELY(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
|
||||
/* x < 0x1p-126 or inf or nan. */
|
||||
if (ix * 2 == 0)
|
||||
return __math_divzerof(1);
|
||||
if (ix == 0x7f800000) /* log2(inf) == inf. */
|
||||
return x;
|
||||
if ((ix & 0x80000000) || ix * 2 >= 0xff000000)
|
||||
return __math_invalidf(x);
|
||||
/* x is subnormal, normalize it. */
|
||||
ix = asuint(x * 0x1p23f);
|
||||
ix -= 23 << 23;
|
||||
}
|
||||
|
||||
/* x = 2^k z; where z is in range [OFF,2*OFF] and exact.
|
||||
The range is split into N subintervals.
|
||||
The ith subinterval contains z and c is near its center. */
|
||||
tmp = ix - OFF;
|
||||
i = (tmp >> (23 - LOG2F_TABLE_BITS)) % N;
|
||||
top = tmp & 0xff800000;
|
||||
iz = ix - top;
|
||||
k = (int32_t)tmp >> 23; /* arithmetic shift */
|
||||
invc = T[i].invc;
|
||||
logc = T[i].logc;
|
||||
z = (double_t)asfloat(iz);
|
||||
|
||||
/* log2(x) = log1p(z/c-1)/ln2 + log2(c) + k */
|
||||
r = z * invc - 1;
|
||||
y0 = logc + (double_t)k;
|
||||
|
||||
/* Pipelined polynomial evaluation to approximate log1p(r)/ln2. */
|
||||
r2 = r * r;
|
||||
y = A[1] * r + A[2];
|
||||
y = A[0] * r2 + y;
|
||||
p = A[3] * r + y0;
|
||||
y = y * r2 + p;
|
||||
return eval_as_float(y);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
66
libc/tinymath/log2f_data.c
Normal file
66
libc/tinymath/log2f_data.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/log2f_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Data definition for log2f.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
const struct log2f_data __log2f_data = {
|
||||
.tab = {
|
||||
{ 0x1.661ec79f8f3bep+0, -0x1.efec65b963019p-2 },
|
||||
{ 0x1.571ed4aaf883dp+0, -0x1.b0b6832d4fca4p-2 },
|
||||
{ 0x1.49539f0f010bp+0, -0x1.7418b0a1fb77bp-2 },
|
||||
{ 0x1.3c995b0b80385p+0, -0x1.39de91a6dcf7bp-2 },
|
||||
{ 0x1.30d190c8864a5p+0, -0x1.01d9bf3f2b631p-2 },
|
||||
{ 0x1.25e227b0b8eap+0, -0x1.97c1d1b3b7afp-3 },
|
||||
{ 0x1.1bb4a4a1a343fp+0, -0x1.2f9e393af3c9fp-3 },
|
||||
{ 0x1.12358f08ae5bap+0, -0x1.960cbbf788d5cp-4 },
|
||||
{ 0x1.0953f419900a7p+0, -0x1.a6f9db6475fcep-5 },
|
||||
{ 0x1p+0, 0x0p+0 },
|
||||
{ 0x1.e608cfd9a47acp-1, 0x1.338ca9f24f53dp-4 },
|
||||
{ 0x1.ca4b31f026aap-1, 0x1.476a9543891bap-3 },
|
||||
{ 0x1.b2036576afce6p-1, 0x1.e840b4ac4e4d2p-3 },
|
||||
{ 0x1.9c2d163a1aa2dp-1, 0x1.40645f0c6651cp-2 },
|
||||
{ 0x1.886e6037841edp-1, 0x1.88e9c2c1b9ff8p-2 },
|
||||
{ 0x1.767dcf5534862p-1, 0x1.ce0a44eb17bccp-2 },
|
||||
},
|
||||
.poly = {
|
||||
-0x1.712b6f70a7e4dp-2, 0x1.ecabf496832ep-2, -0x1.715479ffae3dep-1,
|
||||
0x1.715475f35c8b8p0,
|
||||
}
|
||||
};
|
19
libc/tinymath/log2f_data.internal.h
Normal file
19
libc/tinymath/log2f_data.internal.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_LOG2F_DATA_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_LOG2F_DATA_INTERNAL_H_
|
||||
|
||||
#define LOG2F_TABLE_BITS 4
|
||||
#define LOG2F_POLY_ORDER 4
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct log2f_data {
|
||||
struct {
|
||||
double invc, logc;
|
||||
} tab[1 << LOG2F_TABLE_BITS];
|
||||
double poly[LOG2F_POLY_ORDER];
|
||||
} __log2f_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_LOG2F_DATA_INTERNAL_H_ */
|
361
libc/tinymath/log_data.c
Normal file
361
libc/tinymath/log_data.c
Normal file
|
@ -0,0 +1,361 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/log_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Data for log.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << LOG_TABLE_BITS)
|
||||
|
||||
const struct log_data __log_data = {
|
||||
.ln2hi = 0x1.62e42fefa3800p-1,
|
||||
.ln2lo = 0x1.ef35793c76730p-45,
|
||||
.poly1 = {
|
||||
// relative error: 0x1.c04d76cp-63
|
||||
// in -0x1p-4 0x1.09p-4 (|log(1+x)| > 0x1p-4 outside the interval)
|
||||
-0x1p-1,
|
||||
0x1.5555555555577p-2,
|
||||
-0x1.ffffffffffdcbp-3,
|
||||
0x1.999999995dd0cp-3,
|
||||
-0x1.55555556745a7p-3,
|
||||
0x1.24924a344de3p-3,
|
||||
-0x1.fffffa4423d65p-4,
|
||||
0x1.c7184282ad6cap-4,
|
||||
-0x1.999eb43b068ffp-4,
|
||||
0x1.78182f7afd085p-4,
|
||||
-0x1.5521375d145cdp-4,
|
||||
},
|
||||
.poly = {
|
||||
// relative error: 0x1.926199e8p-56
|
||||
// abs error: 0x1.882ff33p-65
|
||||
// in -0x1.fp-9 0x1.fp-9
|
||||
-0x1.0000000000001p-1,
|
||||
0x1.555555551305bp-2,
|
||||
-0x1.fffffffeb459p-3,
|
||||
0x1.999b324f10111p-3,
|
||||
-0x1.55575e506c89fp-3,
|
||||
},
|
||||
/* Algorithm:
|
||||
|
||||
x = 2^k z
|
||||
log(x) = k ln2 + log(c) + log(z/c)
|
||||
log(z/c) = poly(z/c - 1)
|
||||
|
||||
where z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls
|
||||
into the ith one, then table entries are computed as
|
||||
|
||||
tab[i].invc = 1/c
|
||||
tab[i].logc = (double)log(c)
|
||||
tab2[i].chi = (double)c
|
||||
tab2[i].clo = (double)(c - (double)c)
|
||||
|
||||
where c is near the center of the subinterval and is chosen by trying +-2^29
|
||||
floating point invc candidates around 1/center and selecting one for which
|
||||
|
||||
1) the rounding error in 0x1.8p9 + logc is 0,
|
||||
2) the rounding error in z - chi - clo is < 0x1p-66 and
|
||||
3) the rounding error in (double)log(c) is minimized (< 0x1p-66).
|
||||
|
||||
Note: 1) ensures that k*ln2hi + logc can be computed without rounding error,
|
||||
2) ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to
|
||||
a single rounding error when there is no fast fma for z*invc - 1, 3) ensures
|
||||
that logc + poly(z/c - 1) has small error, however near x == 1 when
|
||||
|log(x)| < 0x1p-4, this is not enough so that is special cased. */
|
||||
.tab = {
|
||||
{0x1.734f0c3e0de9fp+0, -0x1.7cc7f79e69000p-2},
|
||||
{0x1.713786a2ce91fp+0, -0x1.76feec20d0000p-2},
|
||||
{0x1.6f26008fab5a0p+0, -0x1.713e31351e000p-2},
|
||||
{0x1.6d1a61f138c7dp+0, -0x1.6b85b38287800p-2},
|
||||
{0x1.6b1490bc5b4d1p+0, -0x1.65d5590807800p-2},
|
||||
{0x1.69147332f0cbap+0, -0x1.602d076180000p-2},
|
||||
{0x1.6719f18224223p+0, -0x1.5a8ca86909000p-2},
|
||||
{0x1.6524f99a51ed9p+0, -0x1.54f4356035000p-2},
|
||||
{0x1.63356aa8f24c4p+0, -0x1.4f637c36b4000p-2},
|
||||
{0x1.614b36b9ddc14p+0, -0x1.49da7fda85000p-2},
|
||||
{0x1.5f66452c65c4cp+0, -0x1.445923989a800p-2},
|
||||
{0x1.5d867b5912c4fp+0, -0x1.3edf439b0b800p-2},
|
||||
{0x1.5babccb5b90dep+0, -0x1.396ce448f7000p-2},
|
||||
{0x1.59d61f2d91a78p+0, -0x1.3401e17bda000p-2},
|
||||
{0x1.5805612465687p+0, -0x1.2e9e2ef468000p-2},
|
||||
{0x1.56397cee76bd3p+0, -0x1.2941b3830e000p-2},
|
||||
{0x1.54725e2a77f93p+0, -0x1.23ec58cda8800p-2},
|
||||
{0x1.52aff42064583p+0, -0x1.1e9e129279000p-2},
|
||||
{0x1.50f22dbb2bddfp+0, -0x1.1956d2b48f800p-2},
|
||||
{0x1.4f38f4734ded7p+0, -0x1.141679ab9f800p-2},
|
||||
{0x1.4d843cfde2840p+0, -0x1.0edd094ef9800p-2},
|
||||
{0x1.4bd3ec078a3c8p+0, -0x1.09aa518db1000p-2},
|
||||
{0x1.4a27fc3e0258ap+0, -0x1.047e65263b800p-2},
|
||||
{0x1.4880524d48434p+0, -0x1.feb224586f000p-3},
|
||||
{0x1.46dce1b192d0bp+0, -0x1.f474a7517b000p-3},
|
||||
{0x1.453d9d3391854p+0, -0x1.ea4443d103000p-3},
|
||||
{0x1.43a2744b4845ap+0, -0x1.e020d44e9b000p-3},
|
||||
{0x1.420b54115f8fbp+0, -0x1.d60a22977f000p-3},
|
||||
{0x1.40782da3ef4b1p+0, -0x1.cc00104959000p-3},
|
||||
{0x1.3ee8f5d57fe8fp+0, -0x1.c202956891000p-3},
|
||||
{0x1.3d5d9a00b4ce9p+0, -0x1.b81178d811000p-3},
|
||||
{0x1.3bd60c010c12bp+0, -0x1.ae2c9ccd3d000p-3},
|
||||
{0x1.3a5242b75dab8p+0, -0x1.a45402e129000p-3},
|
||||
{0x1.38d22cd9fd002p+0, -0x1.9a877681df000p-3},
|
||||
{0x1.3755bc5847a1cp+0, -0x1.90c6d69483000p-3},
|
||||
{0x1.35dce49ad36e2p+0, -0x1.87120a645c000p-3},
|
||||
{0x1.34679984dd440p+0, -0x1.7d68fb4143000p-3},
|
||||
{0x1.32f5cceffcb24p+0, -0x1.73cb83c627000p-3},
|
||||
{0x1.3187775a10d49p+0, -0x1.6a39a9b376000p-3},
|
||||
{0x1.301c8373e3990p+0, -0x1.60b3154b7a000p-3},
|
||||
{0x1.2eb4ebb95f841p+0, -0x1.5737d76243000p-3},
|
||||
{0x1.2d50a0219a9d1p+0, -0x1.4dc7b8fc23000p-3},
|
||||
{0x1.2bef9a8b7fd2ap+0, -0x1.4462c51d20000p-3},
|
||||
{0x1.2a91c7a0c1babp+0, -0x1.3b08abc830000p-3},
|
||||
{0x1.293726014b530p+0, -0x1.31b996b490000p-3},
|
||||
{0x1.27dfa5757a1f5p+0, -0x1.2875490a44000p-3},
|
||||
{0x1.268b39b1d3bbfp+0, -0x1.1f3b9f879a000p-3},
|
||||
{0x1.2539d838ff5bdp+0, -0x1.160c8252ca000p-3},
|
||||
{0x1.23eb7aac9083bp+0, -0x1.0ce7f57f72000p-3},
|
||||
{0x1.22a012ba940b6p+0, -0x1.03cdc49fea000p-3},
|
||||
{0x1.2157996cc4132p+0, -0x1.f57bdbc4b8000p-4},
|
||||
{0x1.201201dd2fc9bp+0, -0x1.e370896404000p-4},
|
||||
{0x1.1ecf4494d480bp+0, -0x1.d17983ef94000p-4},
|
||||
{0x1.1d8f5528f6569p+0, -0x1.bf9674ed8a000p-4},
|
||||
{0x1.1c52311577e7cp+0, -0x1.adc79202f6000p-4},
|
||||
{0x1.1b17c74cb26e9p+0, -0x1.9c0c3e7288000p-4},
|
||||
{0x1.19e010c2c1ab6p+0, -0x1.8a646b372c000p-4},
|
||||
{0x1.18ab07bb670bdp+0, -0x1.78d01b3ac0000p-4},
|
||||
{0x1.1778a25efbcb6p+0, -0x1.674f145380000p-4},
|
||||
{0x1.1648d354c31dap+0, -0x1.55e0e6d878000p-4},
|
||||
{0x1.151b990275fddp+0, -0x1.4485cdea1e000p-4},
|
||||
{0x1.13f0ea432d24cp+0, -0x1.333d94d6aa000p-4},
|
||||
{0x1.12c8b7210f9dap+0, -0x1.22079f8c56000p-4},
|
||||
{0x1.11a3028ecb531p+0, -0x1.10e4698622000p-4},
|
||||
{0x1.107fbda8434afp+0, -0x1.ffa6c6ad20000p-5},
|
||||
{0x1.0f5ee0f4e6bb3p+0, -0x1.dda8d4a774000p-5},
|
||||
{0x1.0e4065d2a9fcep+0, -0x1.bbcece4850000p-5},
|
||||
{0x1.0d244632ca521p+0, -0x1.9a1894012c000p-5},
|
||||
{0x1.0c0a77ce2981ap+0, -0x1.788583302c000p-5},
|
||||
{0x1.0af2f83c636d1p+0, -0x1.5715e67d68000p-5},
|
||||
{0x1.09ddb98a01339p+0, -0x1.35c8a49658000p-5},
|
||||
{0x1.08cabaf52e7dfp+0, -0x1.149e364154000p-5},
|
||||
{0x1.07b9f2f4e28fbp+0, -0x1.e72c082eb8000p-6},
|
||||
{0x1.06ab58c358f19p+0, -0x1.a55f152528000p-6},
|
||||
{0x1.059eea5ecf92cp+0, -0x1.63d62cf818000p-6},
|
||||
{0x1.04949cdd12c90p+0, -0x1.228fb8caa0000p-6},
|
||||
{0x1.038c6c6f0ada9p+0, -0x1.c317b20f90000p-7},
|
||||
{0x1.02865137932a9p+0, -0x1.419355daa0000p-7},
|
||||
{0x1.0182427ea7348p+0, -0x1.81203c2ec0000p-8},
|
||||
{0x1.008040614b195p+0, -0x1.0040979240000p-9},
|
||||
{0x1.fe01ff726fa1ap-1, 0x1.feff384900000p-9},
|
||||
{0x1.fa11cc261ea74p-1, 0x1.7dc41353d0000p-7},
|
||||
{0x1.f6310b081992ep-1, 0x1.3cea3c4c28000p-6},
|
||||
{0x1.f25f63ceeadcdp-1, 0x1.b9fc114890000p-6},
|
||||
{0x1.ee9c8039113e7p-1, 0x1.1b0d8ce110000p-5},
|
||||
{0x1.eae8078cbb1abp-1, 0x1.58a5bd001c000p-5},
|
||||
{0x1.e741aa29d0c9bp-1, 0x1.95c8340d88000p-5},
|
||||
{0x1.e3a91830a99b5p-1, 0x1.d276aef578000p-5},
|
||||
{0x1.e01e009609a56p-1, 0x1.07598e598c000p-4},
|
||||
{0x1.dca01e577bb98p-1, 0x1.253f5e30d2000p-4},
|
||||
{0x1.d92f20b7c9103p-1, 0x1.42edd8b380000p-4},
|
||||
{0x1.d5cac66fb5ccep-1, 0x1.606598757c000p-4},
|
||||
{0x1.d272caa5ede9dp-1, 0x1.7da76356a0000p-4},
|
||||
{0x1.cf26e3e6b2ccdp-1, 0x1.9ab434e1c6000p-4},
|
||||
{0x1.cbe6da2a77902p-1, 0x1.b78c7bb0d6000p-4},
|
||||
{0x1.c8b266d37086dp-1, 0x1.d431332e72000p-4},
|
||||
{0x1.c5894bd5d5804p-1, 0x1.f0a3171de6000p-4},
|
||||
{0x1.c26b533bb9f8cp-1, 0x1.067152b914000p-3},
|
||||
{0x1.bf583eeece73fp-1, 0x1.147858292b000p-3},
|
||||
{0x1.bc4fd75db96c1p-1, 0x1.2266ecdca3000p-3},
|
||||
{0x1.b951e0c864a28p-1, 0x1.303d7a6c55000p-3},
|
||||
{0x1.b65e2c5ef3e2cp-1, 0x1.3dfc33c331000p-3},
|
||||
{0x1.b374867c9888bp-1, 0x1.4ba366b7a8000p-3},
|
||||
{0x1.b094b211d304ap-1, 0x1.5933928d1f000p-3},
|
||||
{0x1.adbe885f2ef7ep-1, 0x1.66acd2418f000p-3},
|
||||
{0x1.aaf1d31603da2p-1, 0x1.740f8ec669000p-3},
|
||||
{0x1.a82e63fd358a7p-1, 0x1.815c0f51af000p-3},
|
||||
{0x1.a5740ef09738bp-1, 0x1.8e92954f68000p-3},
|
||||
{0x1.a2c2a90ab4b27p-1, 0x1.9bb3602f84000p-3},
|
||||
{0x1.a01a01393f2d1p-1, 0x1.a8bed1c2c0000p-3},
|
||||
{0x1.9d79f24db3c1bp-1, 0x1.b5b515c01d000p-3},
|
||||
{0x1.9ae2505c7b190p-1, 0x1.c2967ccbcc000p-3},
|
||||
{0x1.9852ef297ce2fp-1, 0x1.cf635d5486000p-3},
|
||||
{0x1.95cbaeea44b75p-1, 0x1.dc1bd3446c000p-3},
|
||||
{0x1.934c69de74838p-1, 0x1.e8c01b8cfe000p-3},
|
||||
{0x1.90d4f2f6752e6p-1, 0x1.f5509c0179000p-3},
|
||||
{0x1.8e6528effd79dp-1, 0x1.00e6c121fb800p-2},
|
||||
{0x1.8bfce9fcc007cp-1, 0x1.071b80e93d000p-2},
|
||||
{0x1.899c0dabec30ep-1, 0x1.0d46b9e867000p-2},
|
||||
{0x1.87427aa2317fbp-1, 0x1.13687334bd000p-2},
|
||||
{0x1.84f00acb39a08p-1, 0x1.1980d67234800p-2},
|
||||
{0x1.82a49e8653e55p-1, 0x1.1f8ffe0cc8000p-2},
|
||||
{0x1.8060195f40260p-1, 0x1.2595fd7636800p-2},
|
||||
{0x1.7e22563e0a329p-1, 0x1.2b9300914a800p-2},
|
||||
{0x1.7beb377dcb5adp-1, 0x1.3187210436000p-2},
|
||||
{0x1.79baa679725c2p-1, 0x1.377266dec1800p-2},
|
||||
{0x1.77907f2170657p-1, 0x1.3d54ffbaf3000p-2},
|
||||
{0x1.756cadbd6130cp-1, 0x1.432eee32fe000p-2},
|
||||
},
|
||||
#if !__FP_FAST_FMA
|
||||
.tab2 = {
|
||||
{0x1.61000014fb66bp-1, 0x1.e026c91425b3cp-56},
|
||||
{0x1.63000034db495p-1, 0x1.dbfea48005d41p-55},
|
||||
{0x1.650000d94d478p-1, 0x1.e7fa786d6a5b7p-55},
|
||||
{0x1.67000074e6fadp-1, 0x1.1fcea6b54254cp-57},
|
||||
{0x1.68ffffedf0faep-1, -0x1.c7e274c590efdp-56},
|
||||
{0x1.6b0000763c5bcp-1, -0x1.ac16848dcda01p-55},
|
||||
{0x1.6d0001e5cc1f6p-1, 0x1.33f1c9d499311p-55},
|
||||
{0x1.6efffeb05f63ep-1, -0x1.e80041ae22d53p-56},
|
||||
{0x1.710000e86978p-1, 0x1.bff6671097952p-56},
|
||||
{0x1.72ffffc67e912p-1, 0x1.c00e226bd8724p-55},
|
||||
{0x1.74fffdf81116ap-1, -0x1.e02916ef101d2p-57},
|
||||
{0x1.770000f679c9p-1, -0x1.7fc71cd549c74p-57},
|
||||
{0x1.78ffffa7ec835p-1, 0x1.1bec19ef50483p-55},
|
||||
{0x1.7affffe20c2e6p-1, -0x1.07e1729cc6465p-56},
|
||||
{0x1.7cfffed3fc9p-1, -0x1.08072087b8b1cp-55},
|
||||
{0x1.7efffe9261a76p-1, 0x1.dc0286d9df9aep-55},
|
||||
{0x1.81000049ca3e8p-1, 0x1.97fd251e54c33p-55},
|
||||
{0x1.8300017932c8fp-1, -0x1.afee9b630f381p-55},
|
||||
{0x1.850000633739cp-1, 0x1.9bfbf6b6535bcp-55},
|
||||
{0x1.87000204289c6p-1, -0x1.bbf65f3117b75p-55},
|
||||
{0x1.88fffebf57904p-1, -0x1.9006ea23dcb57p-55},
|
||||
{0x1.8b00022bc04dfp-1, -0x1.d00df38e04b0ap-56},
|
||||
{0x1.8cfffe50c1b8ap-1, -0x1.8007146ff9f05p-55},
|
||||
{0x1.8effffc918e43p-1, 0x1.3817bd07a7038p-55},
|
||||
{0x1.910001efa5fc7p-1, 0x1.93e9176dfb403p-55},
|
||||
{0x1.9300013467bb9p-1, 0x1.f804e4b980276p-56},
|
||||
{0x1.94fffe6ee076fp-1, -0x1.f7ef0d9ff622ep-55},
|
||||
{0x1.96fffde3c12d1p-1, -0x1.082aa962638bap-56},
|
||||
{0x1.98ffff4458a0dp-1, -0x1.7801b9164a8efp-55},
|
||||
{0x1.9afffdd982e3ep-1, -0x1.740e08a5a9337p-55},
|
||||
{0x1.9cfffed49fb66p-1, 0x1.fce08c19bep-60},
|
||||
{0x1.9f00020f19c51p-1, -0x1.a3faa27885b0ap-55},
|
||||
{0x1.a10001145b006p-1, 0x1.4ff489958da56p-56},
|
||||
{0x1.a300007bbf6fap-1, 0x1.cbeab8a2b6d18p-55},
|
||||
{0x1.a500010971d79p-1, 0x1.8fecadd78793p-55},
|
||||
{0x1.a70001df52e48p-1, -0x1.f41763dd8abdbp-55},
|
||||
{0x1.a90001c593352p-1, -0x1.ebf0284c27612p-55},
|
||||
{0x1.ab0002a4f3e4bp-1, -0x1.9fd043cff3f5fp-57},
|
||||
{0x1.acfffd7ae1ed1p-1, -0x1.23ee7129070b4p-55},
|
||||
{0x1.aefffee510478p-1, 0x1.a063ee00edea3p-57},
|
||||
{0x1.b0fffdb650d5bp-1, 0x1.a06c8381f0ab9p-58},
|
||||
{0x1.b2ffffeaaca57p-1, -0x1.9011e74233c1dp-56},
|
||||
{0x1.b4fffd995badcp-1, -0x1.9ff1068862a9fp-56},
|
||||
{0x1.b7000249e659cp-1, 0x1.aff45d0864f3ep-55},
|
||||
{0x1.b8ffff987164p-1, 0x1.cfe7796c2c3f9p-56},
|
||||
{0x1.bafffd204cb4fp-1, -0x1.3ff27eef22bc4p-57},
|
||||
{0x1.bcfffd2415c45p-1, -0x1.cffb7ee3bea21p-57},
|
||||
{0x1.beffff86309dfp-1, -0x1.14103972e0b5cp-55},
|
||||
{0x1.c0fffe1b57653p-1, 0x1.bc16494b76a19p-55},
|
||||
{0x1.c2ffff1fa57e3p-1, -0x1.4feef8d30c6edp-57},
|
||||
{0x1.c4fffdcbfe424p-1, -0x1.43f68bcec4775p-55},
|
||||
{0x1.c6fffed54b9f7p-1, 0x1.47ea3f053e0ecp-55},
|
||||
{0x1.c8fffeb998fd5p-1, 0x1.383068df992f1p-56},
|
||||
{0x1.cb0002125219ap-1, -0x1.8fd8e64180e04p-57},
|
||||
{0x1.ccfffdd94469cp-1, 0x1.e7ebe1cc7ea72p-55},
|
||||
{0x1.cefffeafdc476p-1, 0x1.ebe39ad9f88fep-55},
|
||||
{0x1.d1000169af82bp-1, 0x1.57d91a8b95a71p-56},
|
||||
{0x1.d30000d0ff71dp-1, 0x1.9c1906970c7dap-55},
|
||||
{0x1.d4fffea790fc4p-1, -0x1.80e37c558fe0cp-58},
|
||||
{0x1.d70002edc87e5p-1, -0x1.f80d64dc10f44p-56},
|
||||
{0x1.d900021dc82aap-1, -0x1.47c8f94fd5c5cp-56},
|
||||
{0x1.dafffd86b0283p-1, 0x1.c7f1dc521617ep-55},
|
||||
{0x1.dd000296c4739p-1, 0x1.8019eb2ffb153p-55},
|
||||
{0x1.defffe54490f5p-1, 0x1.e00d2c652cc89p-57},
|
||||
{0x1.e0fffcdabf694p-1, -0x1.f8340202d69d2p-56},
|
||||
{0x1.e2fffdb52c8ddp-1, 0x1.b00c1ca1b0864p-56},
|
||||
{0x1.e4ffff24216efp-1, 0x1.2ffa8b094ab51p-56},
|
||||
{0x1.e6fffe88a5e11p-1, -0x1.7f673b1efbe59p-58},
|
||||
{0x1.e9000119eff0dp-1, -0x1.4808d5e0bc801p-55},
|
||||
{0x1.eafffdfa51744p-1, 0x1.80006d54320b5p-56},
|
||||
{0x1.ed0001a127fa1p-1, -0x1.002f860565c92p-58},
|
||||
{0x1.ef00007babcc4p-1, -0x1.540445d35e611p-55},
|
||||
{0x1.f0ffff57a8d02p-1, -0x1.ffb3139ef9105p-59},
|
||||
{0x1.f30001ee58ac7p-1, 0x1.a81acf2731155p-55},
|
||||
{0x1.f4ffff5823494p-1, 0x1.a3f41d4d7c743p-55},
|
||||
{0x1.f6ffffca94c6bp-1, -0x1.202f41c987875p-57},
|
||||
{0x1.f8fffe1f9c441p-1, 0x1.77dd1f477e74bp-56},
|
||||
{0x1.fafffd2e0e37ep-1, -0x1.f01199a7ca331p-57},
|
||||
{0x1.fd0001c77e49ep-1, 0x1.181ee4bceacb1p-56},
|
||||
{0x1.feffff7e0c331p-1, -0x1.e05370170875ap-57},
|
||||
{0x1.00ffff465606ep+0, -0x1.a7ead491c0adap-55},
|
||||
{0x1.02ffff3867a58p+0, -0x1.77f69c3fcb2ep-54},
|
||||
{0x1.04ffffdfc0d17p+0, 0x1.7bffe34cb945bp-54},
|
||||
{0x1.0700003cd4d82p+0, 0x1.20083c0e456cbp-55},
|
||||
{0x1.08ffff9f2cbe8p+0, -0x1.dffdfbe37751ap-57},
|
||||
{0x1.0b000010cda65p+0, -0x1.13f7faee626ebp-54},
|
||||
{0x1.0d00001a4d338p+0, 0x1.07dfa79489ff7p-55},
|
||||
{0x1.0effffadafdfdp+0, -0x1.7040570d66bcp-56},
|
||||
{0x1.110000bbafd96p+0, 0x1.e80d4846d0b62p-55},
|
||||
{0x1.12ffffae5f45dp+0, 0x1.dbffa64fd36efp-54},
|
||||
{0x1.150000dd59ad9p+0, 0x1.a0077701250aep-54},
|
||||
{0x1.170000f21559ap+0, 0x1.dfdf9e2e3deeep-55},
|
||||
{0x1.18ffffc275426p+0, 0x1.10030dc3b7273p-54},
|
||||
{0x1.1b000123d3c59p+0, 0x1.97f7980030188p-54},
|
||||
{0x1.1cffff8299eb7p+0, -0x1.5f932ab9f8c67p-57},
|
||||
{0x1.1effff48ad4p+0, 0x1.37fbf9da75bebp-54},
|
||||
{0x1.210000c8b86a4p+0, 0x1.f806b91fd5b22p-54},
|
||||
{0x1.2300003854303p+0, 0x1.3ffc2eb9fbf33p-54},
|
||||
{0x1.24fffffbcf684p+0, 0x1.601e77e2e2e72p-56},
|
||||
{0x1.26ffff52921d9p+0, 0x1.ffcbb767f0c61p-56},
|
||||
{0x1.2900014933a3cp+0, -0x1.202ca3c02412bp-56},
|
||||
{0x1.2b00014556313p+0, -0x1.2808233f21f02p-54},
|
||||
{0x1.2cfffebfe523bp+0, -0x1.8ff7e384fdcf2p-55},
|
||||
{0x1.2f0000bb8ad96p+0, -0x1.5ff51503041c5p-55},
|
||||
{0x1.30ffffb7ae2afp+0, -0x1.10071885e289dp-55},
|
||||
{0x1.32ffffeac5f7fp+0, -0x1.1ff5d3fb7b715p-54},
|
||||
{0x1.350000ca66756p+0, 0x1.57f82228b82bdp-54},
|
||||
{0x1.3700011fbf721p+0, 0x1.000bac40dd5ccp-55},
|
||||
{0x1.38ffff9592fb9p+0, -0x1.43f9d2db2a751p-54},
|
||||
{0x1.3b00004ddd242p+0, 0x1.57f6b707638e1p-55},
|
||||
{0x1.3cffff5b2c957p+0, 0x1.a023a10bf1231p-56},
|
||||
{0x1.3efffeab0b418p+0, 0x1.87f6d66b152bp-54},
|
||||
{0x1.410001532aff4p+0, 0x1.7f8375f198524p-57},
|
||||
{0x1.4300017478b29p+0, 0x1.301e672dc5143p-55},
|
||||
{0x1.44fffe795b463p+0, 0x1.9ff69b8b2895ap-55},
|
||||
{0x1.46fffe80475ep+0, -0x1.5c0b19bc2f254p-54},
|
||||
{0x1.48fffef6fc1e7p+0, 0x1.b4009f23a2a72p-54},
|
||||
{0x1.4afffe5bea704p+0, -0x1.4ffb7bf0d7d45p-54},
|
||||
{0x1.4d000171027dep+0, -0x1.9c06471dc6a3dp-54},
|
||||
{0x1.4f0000ff03ee2p+0, 0x1.77f890b85531cp-54},
|
||||
{0x1.5100012dc4bd1p+0, 0x1.004657166a436p-57},
|
||||
{0x1.530001605277ap+0, -0x1.6bfcece233209p-54},
|
||||
{0x1.54fffecdb704cp+0, -0x1.902720505a1d7p-55},
|
||||
{0x1.56fffef5f54a9p+0, 0x1.bbfe60ec96412p-54},
|
||||
{0x1.5900017e61012p+0, 0x1.87ec581afef9p-55},
|
||||
{0x1.5b00003c93e92p+0, -0x1.f41080abf0ccp-54},
|
||||
{0x1.5d0001d4919bcp+0, -0x1.8812afb254729p-54},
|
||||
{0x1.5efffe7b87a89p+0, -0x1.47eb780ed6904p-54},
|
||||
},
|
||||
#endif
|
||||
};
|
28
libc/tinymath/log_data.internal.h
Normal file
28
libc/tinymath/log_data.internal.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_LOG_DATA_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_LOG_DATA_H_
|
||||
|
||||
#define LOG_TABLE_BITS 7
|
||||
#define LOG_POLY_ORDER 6
|
||||
#define LOG_POLY1_ORDER 12
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct log_data {
|
||||
double ln2hi;
|
||||
double ln2lo;
|
||||
double poly[LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
|
||||
double poly1[LOG_POLY1_ORDER - 1];
|
||||
struct {
|
||||
double invc, logc;
|
||||
} tab[1 << LOG_TABLE_BITS];
|
||||
#if !__FP_FAST_FMA
|
||||
struct {
|
||||
double chi, clo;
|
||||
} tab2[1 << LOG_TABLE_BITS];
|
||||
#endif
|
||||
} __log_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_LOG_DATA_H_ */
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#ifdef TINY
|
||||
|
||||
// Returns 𝑥^𝑦.
|
||||
//
|
||||
|
@ -26,3 +27,5 @@
|
|||
pow: ezlea powl,ax
|
||||
jmp _d2ld2
|
||||
.endfn pow,globl
|
||||
|
||||
#endif /* TINY */
|
382
libc/tinymath/pow.c
Normal file
382
libc/tinymath/pow.c
Normal file
|
@ -0,0 +1,382 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/exp_data.internal.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#include "libc/tinymath/pow_data.internal.h"
|
||||
#ifndef TINY
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Double-precision x^y function.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53)
|
||||
relerr_log: 1.3 * 2^-68 (Relative error of log, 1.5 * 2^-68 without fma)
|
||||
ulperr_exp: 0.509 ULP (ULP error of exp, 0.511 ULP without fma)
|
||||
*/
|
||||
|
||||
#define T __pow_log_data.tab
|
||||
#define A __pow_log_data.poly
|
||||
#define Ln2hi __pow_log_data.ln2hi
|
||||
#define Ln2lo __pow_log_data.ln2lo
|
||||
#define N (1 << POW_LOG_TABLE_BITS)
|
||||
#define OFF 0x3fe6955500000000
|
||||
|
||||
/* Top 12 bits of a double (sign and exponent bits). */
|
||||
static inline uint32_t top12(double x)
|
||||
{
|
||||
return asuint64(x) >> 52;
|
||||
}
|
||||
|
||||
/* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about
|
||||
additional 15 bits precision. IX is the bit representation of x, but
|
||||
normalized in the subnormal range using the sign bit for the exponent. */
|
||||
static inline double_t log_inline(uint64_t ix, double_t *tail)
|
||||
{
|
||||
/* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
|
||||
double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p;
|
||||
uint64_t iz, tmp;
|
||||
int k, i;
|
||||
|
||||
/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
|
||||
The range is split into N subintervals.
|
||||
The ith subinterval contains z and c is near its center. */
|
||||
tmp = ix - OFF;
|
||||
i = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N;
|
||||
k = (int64_t)tmp >> 52; /* arithmetic shift */
|
||||
iz = ix - (tmp & 0xfffULL << 52);
|
||||
z = asdouble(iz);
|
||||
kd = (double_t)k;
|
||||
|
||||
/* log(x) = k*Ln2 + log(c) + log1p(z/c-1). */
|
||||
invc = T[i].invc;
|
||||
logc = T[i].logc;
|
||||
logctail = T[i].logctail;
|
||||
|
||||
/* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and
|
||||
|z/c - 1| < 1/N, so r = z/c - 1 is exactly representible. */
|
||||
#if __FP_FAST_FMA
|
||||
r = __builtin_fma(z, invc, -1.0);
|
||||
#else
|
||||
/* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|. */
|
||||
double_t zhi = asdouble((iz + (1ULL << 31)) & (-1ULL << 32));
|
||||
double_t zlo = z - zhi;
|
||||
double_t rhi = zhi * invc - 1.0;
|
||||
double_t rlo = zlo * invc;
|
||||
r = rhi + rlo;
|
||||
#endif
|
||||
|
||||
/* k*Ln2 + log(c) + r. */
|
||||
t1 = kd * Ln2hi + logc;
|
||||
t2 = t1 + r;
|
||||
lo1 = kd * Ln2lo + logctail;
|
||||
lo2 = t1 - t2 + r;
|
||||
|
||||
/* Evaluation is optimized assuming superscalar pipelined execution. */
|
||||
double_t ar, ar2, ar3, lo3, lo4;
|
||||
ar = A[0] * r; /* A[0] = -0.5. */
|
||||
ar2 = r * ar;
|
||||
ar3 = r * ar2;
|
||||
/* k*Ln2 + log(c) + r + A[0]*r*r. */
|
||||
#if __FP_FAST_FMA
|
||||
hi = t2 + ar2;
|
||||
lo3 = __builtin_fma(ar, r, -ar2);
|
||||
lo4 = t2 - hi + ar2;
|
||||
#else
|
||||
double_t arhi = A[0] * rhi;
|
||||
double_t arhi2 = rhi * arhi;
|
||||
hi = t2 + arhi2;
|
||||
lo3 = rlo * (ar + arhi);
|
||||
lo4 = t2 - hi + arhi2;
|
||||
#endif
|
||||
/* p = log1p(r) - r - A[0]*r*r. */
|
||||
p = (ar3 * (A[1] + r * A[2] +
|
||||
ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));
|
||||
lo = lo1 + lo2 + lo3 + lo4 + p;
|
||||
y = hi + lo;
|
||||
*tail = hi - y + lo;
|
||||
return y;
|
||||
}
|
||||
|
||||
#undef N
|
||||
#undef T
|
||||
#define N (1 << EXP_TABLE_BITS)
|
||||
#define InvLn2N __exp_data.invln2N
|
||||
#define NegLn2hiN __exp_data.negln2hiN
|
||||
#define NegLn2loN __exp_data.negln2loN
|
||||
#define Shift __exp_data.shift
|
||||
#define T __exp_data.tab
|
||||
#define C2 __exp_data.poly[5 - EXP_POLY_ORDER]
|
||||
#define C3 __exp_data.poly[6 - EXP_POLY_ORDER]
|
||||
#define C4 __exp_data.poly[7 - EXP_POLY_ORDER]
|
||||
#define C5 __exp_data.poly[8 - EXP_POLY_ORDER]
|
||||
#define C6 __exp_data.poly[9 - EXP_POLY_ORDER]
|
||||
|
||||
/* Handle cases that may overflow or underflow when computing the result that
|
||||
is scale*(1+TMP) without intermediate rounding. The bit representation of
|
||||
scale is in SBITS, however it has a computed exponent that may have
|
||||
overflown into the sign bit so that needs to be adjusted before using it as
|
||||
a double. (int32_t)KI is the k used in the argument reduction and exponent
|
||||
adjustment of scale, positive k here means the result may overflow and
|
||||
negative k means the result may underflow. */
|
||||
static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
|
||||
{
|
||||
double_t scale, y;
|
||||
|
||||
if ((ki & 0x80000000) == 0) {
|
||||
/* k > 0, the exponent of scale might have overflowed by <= 460. */
|
||||
sbits -= 1009ull << 52;
|
||||
scale = asdouble(sbits);
|
||||
y = 0x1p1009 * (scale + scale * tmp);
|
||||
return eval_as_double(y);
|
||||
}
|
||||
/* k < 0, need special care in the subnormal range. */
|
||||
sbits += 1022ull << 52;
|
||||
/* Note: sbits is signed scale. */
|
||||
scale = asdouble(sbits);
|
||||
y = scale + scale * tmp;
|
||||
if (fabs(y) < 1.0) {
|
||||
/* Round y to the right precision before scaling it into the subnormal
|
||||
range to avoid double rounding that can cause 0.5+E/2 ulp error where
|
||||
E is the worst-case ulp error outside the subnormal range. So this
|
||||
is only useful if the goal is better than 1 ulp worst-case error. */
|
||||
double_t hi, lo, one = 1.0;
|
||||
if (y < 0.0)
|
||||
one = -1.0;
|
||||
lo = scale - y + scale * tmp;
|
||||
hi = one + y;
|
||||
lo = one - hi + y + lo;
|
||||
y = eval_as_double(hi + lo) - one;
|
||||
/* Fix the sign of 0. */
|
||||
if (y == 0.0)
|
||||
y = asdouble(sbits & 0x8000000000000000);
|
||||
/* The underflow exception needs to be signaled explicitly. */
|
||||
fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);
|
||||
}
|
||||
y = 0x1p-1022 * y;
|
||||
return eval_as_double(y);
|
||||
}
|
||||
|
||||
#define SIGN_BIAS (0x800 << EXP_TABLE_BITS)
|
||||
|
||||
/* Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.
|
||||
The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1. */
|
||||
static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
|
||||
{
|
||||
uint32_t abstop;
|
||||
uint64_t ki, idx, top, sbits;
|
||||
/* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
|
||||
double_t kd, z, r, r2, scale, tail, tmp;
|
||||
|
||||
abstop = top12(x) & 0x7ff;
|
||||
if (UNLIKELY(abstop - top12(0x1p-54) >=
|
||||
top12(512.0) - top12(0x1p-54))) {
|
||||
if (abstop - top12(0x1p-54) >= 0x80000000) {
|
||||
/* Avoid spurious underflow for tiny x. */
|
||||
/* Note: 0 is common input. */
|
||||
double_t one = WANT_ROUNDING ? 1.0 + x : 1.0;
|
||||
return sign_bias ? -one : one;
|
||||
}
|
||||
if (abstop >= top12(1024.0)) {
|
||||
/* Note: inf and nan are already handled. */
|
||||
if (asuint64(x) >> 63)
|
||||
return __math_uflow(sign_bias);
|
||||
else
|
||||
return __math_oflow(sign_bias);
|
||||
}
|
||||
/* Large x is special cased below. */
|
||||
abstop = 0;
|
||||
}
|
||||
|
||||
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
|
||||
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
|
||||
z = InvLn2N * x;
|
||||
#if TOINT_INTRINSICS
|
||||
kd = roundtoint(z);
|
||||
ki = converttoint(z);
|
||||
#elif EXP_USE_TOINT_NARROW
|
||||
/* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */
|
||||
kd = eval_as_double(z + Shift);
|
||||
ki = asuint64(kd) >> 16;
|
||||
kd = (double_t)(int32_t)ki;
|
||||
#else
|
||||
/* z - kd is in [-1, 1] in non-nearest rounding modes. */
|
||||
kd = eval_as_double(z + Shift);
|
||||
ki = asuint64(kd);
|
||||
kd -= Shift;
|
||||
#endif
|
||||
r = x + kd * NegLn2hiN + kd * NegLn2loN;
|
||||
/* The code assumes 2^-200 < |xtail| < 2^-8/N. */
|
||||
r += xtail;
|
||||
/* 2^(k/N) ~= scale * (1 + tail). */
|
||||
idx = 2 * (ki % N);
|
||||
top = (ki + sign_bias) << (52 - EXP_TABLE_BITS);
|
||||
tail = asdouble(T[idx]);
|
||||
/* This is only a valid scale when -1023*N < k < 1024*N. */
|
||||
sbits = T[idx + 1] + top;
|
||||
/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */
|
||||
/* Evaluation is optimized assuming superscalar pipelined execution. */
|
||||
r2 = r * r;
|
||||
/* Without fma the worst case error is 0.25/N ulp larger. */
|
||||
/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */
|
||||
tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
|
||||
if (UNLIKELY(abstop == 0))
|
||||
return specialcase(tmp, sbits, ki);
|
||||
scale = asdouble(sbits);
|
||||
/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
|
||||
is no spurious underflow here even without fma. */
|
||||
return eval_as_double(scale + scale * tmp);
|
||||
}
|
||||
|
||||
/* Returns 0 if not int, 1 if odd int, 2 if even int. The argument is
|
||||
the bit representation of a non-zero finite floating-point value. */
|
||||
static inline int checkint(uint64_t iy)
|
||||
{
|
||||
int e = iy >> 52 & 0x7ff;
|
||||
if (e < 0x3ff)
|
||||
return 0;
|
||||
if (e > 0x3ff + 52)
|
||||
return 2;
|
||||
if (iy & ((1ULL << (0x3ff + 52 - e)) - 1))
|
||||
return 0;
|
||||
if (iy & (1ULL << (0x3ff + 52 - e)))
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Returns 1 if input is the bit representation of 0, infinity or nan. */
|
||||
static inline int zeroinfnan(uint64_t i)
|
||||
{
|
||||
return 2 * i - 1 >= 2 * asuint64(INFINITY) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 𝑥^𝑦.
|
||||
*/
|
||||
double pow(double x, double y)
|
||||
{
|
||||
uint32_t sign_bias = 0;
|
||||
uint64_t ix, iy;
|
||||
uint32_t topx, topy;
|
||||
|
||||
ix = asuint64(x);
|
||||
iy = asuint64(y);
|
||||
topx = top12(x);
|
||||
topy = top12(y);
|
||||
if (UNLIKELY(topx - 0x001 >= 0x7ff - 0x001 ||
|
||||
(topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) {
|
||||
/* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0
|
||||
and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */
|
||||
/* Special cases: (x < 0x1p-126 or inf or nan) or
|
||||
(|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */
|
||||
if (UNLIKELY(zeroinfnan(iy))) {
|
||||
if (2 * iy == 0)
|
||||
return issignaling_inline(x) ? x + y : 1.0;
|
||||
if (ix == asuint64(1.0))
|
||||
return issignaling_inline(y) ? x + y : 1.0;
|
||||
if (2 * ix > 2 * asuint64(INFINITY) ||
|
||||
2 * iy > 2 * asuint64(INFINITY))
|
||||
return x + y;
|
||||
if (2 * ix == 2 * asuint64(1.0))
|
||||
return 1.0;
|
||||
if ((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63))
|
||||
return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */
|
||||
return y * y;
|
||||
}
|
||||
if (UNLIKELY(zeroinfnan(ix))) {
|
||||
double_t x2 = x * x;
|
||||
if (ix >> 63 && checkint(iy) == 1)
|
||||
x2 = -x2;
|
||||
/* Without the barrier some versions of clang hoist the 1/x2 and
|
||||
thus division by zero exception can be signaled spuriously. */
|
||||
return iy >> 63 ? fp_barrier(1 / x2) : x2;
|
||||
}
|
||||
/* Here x and y are non-zero finite. */
|
||||
if (ix >> 63) {
|
||||
/* Finite x < 0. */
|
||||
int yint = checkint(iy);
|
||||
if (yint == 0)
|
||||
return __math_invalid(x);
|
||||
if (yint == 1)
|
||||
sign_bias = SIGN_BIAS;
|
||||
ix &= 0x7fffffffffffffff;
|
||||
topx &= 0x7ff;
|
||||
}
|
||||
if ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) {
|
||||
/* Note: sign_bias == 0 here because y is not odd. */
|
||||
if (ix == asuint64(1.0))
|
||||
return 1.0;
|
||||
if ((topy & 0x7ff) < 0x3be) {
|
||||
/* |y| < 2^-65, x^y ~= 1 + y*log(x). */
|
||||
if (WANT_ROUNDING)
|
||||
return ix > asuint64(1.0) ? 1.0 + y :
|
||||
1.0 - y;
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
return (ix > asuint64(1.0)) == (topy < 0x800) ?
|
||||
__math_oflow(0) :
|
||||
__math_uflow(0);
|
||||
}
|
||||
if (topx == 0) {
|
||||
/* Normalize subnormal x so exponent becomes negative. */
|
||||
ix = asuint64(x * 0x1p52);
|
||||
ix &= 0x7fffffffffffffff;
|
||||
ix -= 52ULL << 52;
|
||||
}
|
||||
}
|
||||
|
||||
double_t lo;
|
||||
double_t hi = log_inline(ix, &lo);
|
||||
double_t ehi, elo;
|
||||
#if __FP_FAST_FMA
|
||||
ehi = y * hi;
|
||||
elo = y * lo + __builtin_fma(y, hi, -ehi);
|
||||
#else
|
||||
double_t yhi = asdouble(iy & -1ULL << 27);
|
||||
double_t ylo = y - yhi;
|
||||
double_t lhi = asdouble(asuint64(hi) & -1ULL << 27);
|
||||
double_t llo = hi - lhi + lo;
|
||||
ehi = yhi * lhi;
|
||||
elo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25. */
|
||||
#endif
|
||||
return exp_inline(ehi, elo, sign_bias);
|
||||
}
|
||||
|
||||
#endif /* !TINY */
|
213
libc/tinymath/pow_data.c
Normal file
213
libc/tinymath/pow_data.c
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/tinymath/pow_data.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Double-precision math functions (MIT License)\\n\
|
||||
Copyright 2018 ARM Limited\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Data for the log part of pow.
|
||||
*
|
||||
* Copyright (c) 2018, Arm Limited.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define N (1 << POW_LOG_TABLE_BITS)
|
||||
|
||||
const struct pow_log_data __pow_log_data = {
|
||||
.ln2hi = 0x1.62e42fefa3800p-1,
|
||||
.ln2lo = 0x1.ef35793c76730p-45,
|
||||
.poly = {
|
||||
// relative error: 0x1.11922ap-70
|
||||
// in -0x1.6bp-8 0x1.6bp-8
|
||||
// Coefficients are scaled to match the scaling during evaluation.
|
||||
-0x1p-1,
|
||||
0x1.555555555556p-2 * -2,
|
||||
-0x1.0000000000006p-2 * -2,
|
||||
0x1.999999959554ep-3 * 4,
|
||||
-0x1.555555529a47ap-3 * 4,
|
||||
0x1.2495b9b4845e9p-3 * -8,
|
||||
-0x1.0002b8b263fc3p-3 * -8,
|
||||
},
|
||||
/* Algorithm:
|
||||
|
||||
x = 2^k z
|
||||
log(x) = k ln2 + log(c) + log(z/c)
|
||||
log(z/c) = poly(z/c - 1)
|
||||
|
||||
where z is in [0x1.69555p-1; 0x1.69555p0] which is split into N subintervals
|
||||
and z falls into the ith one, then table entries are computed as
|
||||
|
||||
tab[i].invc = 1/c
|
||||
tab[i].logc = round(0x1p43*log(c))/0x1p43
|
||||
tab[i].logctail = (double)(log(c) - logc)
|
||||
|
||||
where c is chosen near the center of the subinterval such that 1/c has only a
|
||||
few precision bits so z/c - 1 is exactly representible as double:
|
||||
|
||||
1/c = center < 1 ? round(N/center)/N : round(2*N/center)/N/2
|
||||
|
||||
Note: |z/c - 1| < 1/N for the chosen c, |log(c) - logc - logctail| < 0x1p-97,
|
||||
the last few bits of logc are rounded away so k*ln2hi + logc has no rounding
|
||||
error and the interval for z is selected such that near x == 1, where log(x)
|
||||
is tiny, large cancellation error is avoided in logc + poly(z/c - 1). */
|
||||
.tab = {
|
||||
#define A(a, b, c) {a, 0, b, c},
|
||||
A(0x1.6a00000000000p+0, -0x1.62c82f2b9c800p-2, 0x1.ab42428375680p-48)
|
||||
A(0x1.6800000000000p+0, -0x1.5d1bdbf580800p-2, -0x1.ca508d8e0f720p-46)
|
||||
A(0x1.6600000000000p+0, -0x1.5767717455800p-2, -0x1.362a4d5b6506dp-45)
|
||||
A(0x1.6400000000000p+0, -0x1.51aad872df800p-2, -0x1.684e49eb067d5p-49)
|
||||
A(0x1.6200000000000p+0, -0x1.4be5f95777800p-2, -0x1.41b6993293ee0p-47)
|
||||
A(0x1.6000000000000p+0, -0x1.4618bc21c6000p-2, 0x1.3d82f484c84ccp-46)
|
||||
A(0x1.5e00000000000p+0, -0x1.404308686a800p-2, 0x1.c42f3ed820b3ap-50)
|
||||
A(0x1.5c00000000000p+0, -0x1.3a64c55694800p-2, 0x1.0b1c686519460p-45)
|
||||
A(0x1.5a00000000000p+0, -0x1.347dd9a988000p-2, 0x1.5594dd4c58092p-45)
|
||||
A(0x1.5800000000000p+0, -0x1.2e8e2bae12000p-2, 0x1.67b1e99b72bd8p-45)
|
||||
A(0x1.5600000000000p+0, -0x1.2895a13de8800p-2, 0x1.5ca14b6cfb03fp-46)
|
||||
A(0x1.5600000000000p+0, -0x1.2895a13de8800p-2, 0x1.5ca14b6cfb03fp-46)
|
||||
A(0x1.5400000000000p+0, -0x1.22941fbcf7800p-2, -0x1.65a242853da76p-46)
|
||||
A(0x1.5200000000000p+0, -0x1.1c898c1699800p-2, -0x1.fafbc68e75404p-46)
|
||||
A(0x1.5000000000000p+0, -0x1.1675cababa800p-2, 0x1.f1fc63382a8f0p-46)
|
||||
A(0x1.4e00000000000p+0, -0x1.1058bf9ae4800p-2, -0x1.6a8c4fd055a66p-45)
|
||||
A(0x1.4c00000000000p+0, -0x1.0a324e2739000p-2, -0x1.c6bee7ef4030ep-47)
|
||||
A(0x1.4a00000000000p+0, -0x1.0402594b4d000p-2, -0x1.036b89ef42d7fp-48)
|
||||
A(0x1.4a00000000000p+0, -0x1.0402594b4d000p-2, -0x1.036b89ef42d7fp-48)
|
||||
A(0x1.4800000000000p+0, -0x1.fb9186d5e4000p-3, 0x1.d572aab993c87p-47)
|
||||
A(0x1.4600000000000p+0, -0x1.ef0adcbdc6000p-3, 0x1.b26b79c86af24p-45)
|
||||
A(0x1.4400000000000p+0, -0x1.e27076e2af000p-3, -0x1.72f4f543fff10p-46)
|
||||
A(0x1.4200000000000p+0, -0x1.d5c216b4fc000p-3, 0x1.1ba91bbca681bp-45)
|
||||
A(0x1.4000000000000p+0, -0x1.c8ff7c79aa000p-3, 0x1.7794f689f8434p-45)
|
||||
A(0x1.4000000000000p+0, -0x1.c8ff7c79aa000p-3, 0x1.7794f689f8434p-45)
|
||||
A(0x1.3e00000000000p+0, -0x1.bc286742d9000p-3, 0x1.94eb0318bb78fp-46)
|
||||
A(0x1.3c00000000000p+0, -0x1.af3c94e80c000p-3, 0x1.a4e633fcd9066p-52)
|
||||
A(0x1.3a00000000000p+0, -0x1.a23bc1fe2b000p-3, -0x1.58c64dc46c1eap-45)
|
||||
A(0x1.3a00000000000p+0, -0x1.a23bc1fe2b000p-3, -0x1.58c64dc46c1eap-45)
|
||||
A(0x1.3800000000000p+0, -0x1.9525a9cf45000p-3, -0x1.ad1d904c1d4e3p-45)
|
||||
A(0x1.3600000000000p+0, -0x1.87fa06520d000p-3, 0x1.bbdbf7fdbfa09p-45)
|
||||
A(0x1.3400000000000p+0, -0x1.7ab890210e000p-3, 0x1.bdb9072534a58p-45)
|
||||
A(0x1.3400000000000p+0, -0x1.7ab890210e000p-3, 0x1.bdb9072534a58p-45)
|
||||
A(0x1.3200000000000p+0, -0x1.6d60fe719d000p-3, -0x1.0e46aa3b2e266p-46)
|
||||
A(0x1.3000000000000p+0, -0x1.5ff3070a79000p-3, -0x1.e9e439f105039p-46)
|
||||
A(0x1.3000000000000p+0, -0x1.5ff3070a79000p-3, -0x1.e9e439f105039p-46)
|
||||
A(0x1.2e00000000000p+0, -0x1.526e5e3a1b000p-3, -0x1.0de8b90075b8fp-45)
|
||||
A(0x1.2c00000000000p+0, -0x1.44d2b6ccb8000p-3, 0x1.70cc16135783cp-46)
|
||||
A(0x1.2c00000000000p+0, -0x1.44d2b6ccb8000p-3, 0x1.70cc16135783cp-46)
|
||||
A(0x1.2a00000000000p+0, -0x1.371fc201e9000p-3, 0x1.178864d27543ap-48)
|
||||
A(0x1.2800000000000p+0, -0x1.29552f81ff000p-3, -0x1.48d301771c408p-45)
|
||||
A(0x1.2600000000000p+0, -0x1.1b72ad52f6000p-3, -0x1.e80a41811a396p-45)
|
||||
A(0x1.2600000000000p+0, -0x1.1b72ad52f6000p-3, -0x1.e80a41811a396p-45)
|
||||
A(0x1.2400000000000p+0, -0x1.0d77e7cd09000p-3, 0x1.a699688e85bf4p-47)
|
||||
A(0x1.2400000000000p+0, -0x1.0d77e7cd09000p-3, 0x1.a699688e85bf4p-47)
|
||||
A(0x1.2200000000000p+0, -0x1.fec9131dbe000p-4, -0x1.575545ca333f2p-45)
|
||||
A(0x1.2000000000000p+0, -0x1.e27076e2b0000p-4, 0x1.a342c2af0003cp-45)
|
||||
A(0x1.2000000000000p+0, -0x1.e27076e2b0000p-4, 0x1.a342c2af0003cp-45)
|
||||
A(0x1.1e00000000000p+0, -0x1.c5e548f5bc000p-4, -0x1.d0c57585fbe06p-46)
|
||||
A(0x1.1c00000000000p+0, -0x1.a926d3a4ae000p-4, 0x1.53935e85baac8p-45)
|
||||
A(0x1.1c00000000000p+0, -0x1.a926d3a4ae000p-4, 0x1.53935e85baac8p-45)
|
||||
A(0x1.1a00000000000p+0, -0x1.8c345d631a000p-4, 0x1.37c294d2f5668p-46)
|
||||
A(0x1.1a00000000000p+0, -0x1.8c345d631a000p-4, 0x1.37c294d2f5668p-46)
|
||||
A(0x1.1800000000000p+0, -0x1.6f0d28ae56000p-4, -0x1.69737c93373dap-45)
|
||||
A(0x1.1600000000000p+0, -0x1.51b073f062000p-4, 0x1.f025b61c65e57p-46)
|
||||
A(0x1.1600000000000p+0, -0x1.51b073f062000p-4, 0x1.f025b61c65e57p-46)
|
||||
A(0x1.1400000000000p+0, -0x1.341d7961be000p-4, 0x1.c5edaccf913dfp-45)
|
||||
A(0x1.1400000000000p+0, -0x1.341d7961be000p-4, 0x1.c5edaccf913dfp-45)
|
||||
A(0x1.1200000000000p+0, -0x1.16536eea38000p-4, 0x1.47c5e768fa309p-46)
|
||||
A(0x1.1000000000000p+0, -0x1.f0a30c0118000p-5, 0x1.d599e83368e91p-45)
|
||||
A(0x1.1000000000000p+0, -0x1.f0a30c0118000p-5, 0x1.d599e83368e91p-45)
|
||||
A(0x1.0e00000000000p+0, -0x1.b42dd71198000p-5, 0x1.c827ae5d6704cp-46)
|
||||
A(0x1.0e00000000000p+0, -0x1.b42dd71198000p-5, 0x1.c827ae5d6704cp-46)
|
||||
A(0x1.0c00000000000p+0, -0x1.77458f632c000p-5, -0x1.cfc4634f2a1eep-45)
|
||||
A(0x1.0c00000000000p+0, -0x1.77458f632c000p-5, -0x1.cfc4634f2a1eep-45)
|
||||
A(0x1.0a00000000000p+0, -0x1.39e87b9fec000p-5, 0x1.502b7f526feaap-48)
|
||||
A(0x1.0a00000000000p+0, -0x1.39e87b9fec000p-5, 0x1.502b7f526feaap-48)
|
||||
A(0x1.0800000000000p+0, -0x1.f829b0e780000p-6, -0x1.980267c7e09e4p-45)
|
||||
A(0x1.0800000000000p+0, -0x1.f829b0e780000p-6, -0x1.980267c7e09e4p-45)
|
||||
A(0x1.0600000000000p+0, -0x1.7b91b07d58000p-6, -0x1.88d5493faa639p-45)
|
||||
A(0x1.0400000000000p+0, -0x1.fc0a8b0fc0000p-7, -0x1.f1e7cf6d3a69cp-50)
|
||||
A(0x1.0400000000000p+0, -0x1.fc0a8b0fc0000p-7, -0x1.f1e7cf6d3a69cp-50)
|
||||
A(0x1.0200000000000p+0, -0x1.fe02a6b100000p-8, -0x1.9e23f0dda40e4p-46)
|
||||
A(0x1.0200000000000p+0, -0x1.fe02a6b100000p-8, -0x1.9e23f0dda40e4p-46)
|
||||
A(0x1.0000000000000p+0, 0x0.0000000000000p+0, 0x0.0000000000000p+0)
|
||||
A(0x1.0000000000000p+0, 0x0.0000000000000p+0, 0x0.0000000000000p+0)
|
||||
A(0x1.fc00000000000p-1, 0x1.0101575890000p-7, -0x1.0c76b999d2be8p-46)
|
||||
A(0x1.f800000000000p-1, 0x1.0205658938000p-6, -0x1.3dc5b06e2f7d2p-45)
|
||||
A(0x1.f400000000000p-1, 0x1.8492528c90000p-6, -0x1.aa0ba325a0c34p-45)
|
||||
A(0x1.f000000000000p-1, 0x1.0415d89e74000p-5, 0x1.111c05cf1d753p-47)
|
||||
A(0x1.ec00000000000p-1, 0x1.466aed42e0000p-5, -0x1.c167375bdfd28p-45)
|
||||
A(0x1.e800000000000p-1, 0x1.894aa149fc000p-5, -0x1.97995d05a267dp-46)
|
||||
A(0x1.e400000000000p-1, 0x1.ccb73cdddc000p-5, -0x1.a68f247d82807p-46)
|
||||
A(0x1.e200000000000p-1, 0x1.eea31c006c000p-5, -0x1.e113e4fc93b7bp-47)
|
||||
A(0x1.de00000000000p-1, 0x1.1973bd1466000p-4, -0x1.5325d560d9e9bp-45)
|
||||
A(0x1.da00000000000p-1, 0x1.3bdf5a7d1e000p-4, 0x1.cc85ea5db4ed7p-45)
|
||||
A(0x1.d600000000000p-1, 0x1.5e95a4d97a000p-4, -0x1.c69063c5d1d1ep-45)
|
||||
A(0x1.d400000000000p-1, 0x1.700d30aeac000p-4, 0x1.c1e8da99ded32p-49)
|
||||
A(0x1.d000000000000p-1, 0x1.9335e5d594000p-4, 0x1.3115c3abd47dap-45)
|
||||
A(0x1.cc00000000000p-1, 0x1.b6ac88dad6000p-4, -0x1.390802bf768e5p-46)
|
||||
A(0x1.ca00000000000p-1, 0x1.c885801bc4000p-4, 0x1.646d1c65aacd3p-45)
|
||||
A(0x1.c600000000000p-1, 0x1.ec739830a2000p-4, -0x1.dc068afe645e0p-45)
|
||||
A(0x1.c400000000000p-1, 0x1.fe89139dbe000p-4, -0x1.534d64fa10afdp-45)
|
||||
A(0x1.c000000000000p-1, 0x1.1178e8227e000p-3, 0x1.1ef78ce2d07f2p-45)
|
||||
A(0x1.be00000000000p-1, 0x1.1aa2b7e23f000p-3, 0x1.ca78e44389934p-45)
|
||||
A(0x1.ba00000000000p-1, 0x1.2d1610c868000p-3, 0x1.39d6ccb81b4a1p-47)
|
||||
A(0x1.b800000000000p-1, 0x1.365fcb0159000p-3, 0x1.62fa8234b7289p-51)
|
||||
A(0x1.b400000000000p-1, 0x1.4913d8333b000p-3, 0x1.5837954fdb678p-45)
|
||||
A(0x1.b200000000000p-1, 0x1.527e5e4a1b000p-3, 0x1.633e8e5697dc7p-45)
|
||||
A(0x1.ae00000000000p-1, 0x1.6574ebe8c1000p-3, 0x1.9cf8b2c3c2e78p-46)
|
||||
A(0x1.ac00000000000p-1, 0x1.6f0128b757000p-3, -0x1.5118de59c21e1p-45)
|
||||
A(0x1.aa00000000000p-1, 0x1.7898d85445000p-3, -0x1.c661070914305p-46)
|
||||
A(0x1.a600000000000p-1, 0x1.8beafeb390000p-3, -0x1.73d54aae92cd1p-47)
|
||||
A(0x1.a400000000000p-1, 0x1.95a5adcf70000p-3, 0x1.7f22858a0ff6fp-47)
|
||||
A(0x1.a000000000000p-1, 0x1.a93ed3c8ae000p-3, -0x1.8724350562169p-45)
|
||||
A(0x1.9e00000000000p-1, 0x1.b31d8575bd000p-3, -0x1.c358d4eace1aap-47)
|
||||
A(0x1.9c00000000000p-1, 0x1.bd087383be000p-3, -0x1.d4bc4595412b6p-45)
|
||||
A(0x1.9a00000000000p-1, 0x1.c6ffbc6f01000p-3, -0x1.1ec72c5962bd2p-48)
|
||||
A(0x1.9600000000000p-1, 0x1.db13db0d49000p-3, -0x1.aff2af715b035p-45)
|
||||
A(0x1.9400000000000p-1, 0x1.e530effe71000p-3, 0x1.212276041f430p-51)
|
||||
A(0x1.9200000000000p-1, 0x1.ef5ade4dd0000p-3, -0x1.a211565bb8e11p-51)
|
||||
A(0x1.9000000000000p-1, 0x1.f991c6cb3b000p-3, 0x1.bcbecca0cdf30p-46)
|
||||
A(0x1.8c00000000000p-1, 0x1.07138604d5800p-2, 0x1.89cdb16ed4e91p-48)
|
||||
A(0x1.8a00000000000p-1, 0x1.0c42d67616000p-2, 0x1.7188b163ceae9p-45)
|
||||
A(0x1.8800000000000p-1, 0x1.1178e8227e800p-2, -0x1.c210e63a5f01cp-45)
|
||||
A(0x1.8600000000000p-1, 0x1.16b5ccbacf800p-2, 0x1.b9acdf7a51681p-45)
|
||||
A(0x1.8400000000000p-1, 0x1.1bf99635a6800p-2, 0x1.ca6ed5147bdb7p-45)
|
||||
A(0x1.8200000000000p-1, 0x1.214456d0eb800p-2, 0x1.a87deba46baeap-47)
|
||||
A(0x1.7e00000000000p-1, 0x1.2bef07cdc9000p-2, 0x1.a9cfa4a5004f4p-45)
|
||||
A(0x1.7c00000000000p-1, 0x1.314f1e1d36000p-2, -0x1.8e27ad3213cb8p-45)
|
||||
A(0x1.7a00000000000p-1, 0x1.36b6776be1000p-2, 0x1.16ecdb0f177c8p-46)
|
||||
A(0x1.7800000000000p-1, 0x1.3c25277333000p-2, 0x1.83b54b606bd5cp-46)
|
||||
A(0x1.7600000000000p-1, 0x1.419b423d5e800p-2, 0x1.8e436ec90e09dp-47)
|
||||
A(0x1.7400000000000p-1, 0x1.4718dc271c800p-2, -0x1.f27ce0967d675p-45)
|
||||
A(0x1.7200000000000p-1, 0x1.4c9e09e173000p-2, -0x1.e20891b0ad8a4p-45)
|
||||
A(0x1.7000000000000p-1, 0x1.522ae0738a000p-2, 0x1.ebe708164c759p-45)
|
||||
A(0x1.6e00000000000p-1, 0x1.57bf753c8d000p-2, 0x1.fadedee5d40efp-46)
|
||||
A(0x1.6c00000000000p-1, 0x1.5d5bddf596000p-2, -0x1.a0b2a08a465dcp-47)
|
||||
},
|
||||
};
|
22
libc/tinymath/pow_data.internal.h
Normal file
22
libc/tinymath/pow_data.internal.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TINYMATH_POW_DATA_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_TINYMATH_POW_DATA_INTERNAL_H_
|
||||
|
||||
#define POW_LOG_TABLE_BITS 7
|
||||
#define POW_LOG_POLY_ORDER 8
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern hidden const struct pow_log_data {
|
||||
double ln2hi;
|
||||
double ln2lo;
|
||||
double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
|
||||
/* Note: the pad field is unused, but allows slightly faster indexing. */
|
||||
struct {
|
||||
double invc, pad, logc, logctail;
|
||||
} tab[1 << POW_LOG_TABLE_BITS];
|
||||
} __pow_log_data;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TINYMATH_POW_DATA_INTERNAL_H_ */
|
|
@ -26,6 +26,7 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/kernel.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
fdlibm (fdlibm license)\\n\
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/kernel.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
fdlibm (fdlibm license)\\n\
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// Rounds to integer, toward zero.
|
||||
//
|
||||
// @param 𝑥 is double scalar in low half of %xmm0
|
||||
// @return double scalar in low half of %xmm0
|
||||
// @define trunc(𝑥+copysign(.5,𝑥))
|
||||
// @see round(),rint(),nearbyint()
|
||||
// @see roundsd $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0
|
||||
trunc: .leafprologue
|
||||
.profilable
|
||||
movsd 3f(%rip),%xmm2
|
||||
movsd 2f(%rip),%xmm4
|
||||
movapd %xmm0,%xmm3
|
||||
movapd %xmm0,%xmm1
|
||||
andpd %xmm2,%xmm3
|
||||
ucomisd %xmm3,%xmm4
|
||||
jbe 1f
|
||||
cvttsd2siq %xmm0,%rax
|
||||
pxor %xmm0,%xmm0
|
||||
andnpd %xmm1,%xmm2
|
||||
cvtsi2sdq %rax,%xmm0
|
||||
orpd %xmm2,%xmm0
|
||||
1: .leafepilogue
|
||||
.endfn trunc,globl
|
||||
|
||||
.rodata.cst8
|
||||
2: .long 0x00000000
|
||||
.long 0x43300000
|
||||
.rodata.cst16
|
||||
3: .long 0xffffffff
|
||||
.long 0x7fffffff
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
55
libc/tinymath/trunc.c
Normal file
55
libc/tinymath/trunc.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/**
|
||||
* Rounds to integer, towards zero.
|
||||
*/
|
||||
double trunc(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
|
||||
uint64_t m;
|
||||
if (e >= 52 + 12)
|
||||
return x;
|
||||
if (e < 12)
|
||||
e = 1;
|
||||
m = -1ULL >> e;
|
||||
if ((u.i & m) == 0)
|
||||
return x;
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
u.i &= ~m;
|
||||
return u.f;
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -53,3 +54,12 @@ TEST(ceill, test) {
|
|||
EXPECT_STREQ("INFINITY", gc(xdtoal(ceill(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoal(ceill(-INFINITY))));
|
||||
}
|
||||
|
||||
BENCH(ceill, bench) {
|
||||
double _ceil(double) asm("ceil");
|
||||
float _ceilf(float) asm("ceilf");
|
||||
long double _ceill(long double) asm("ceill");
|
||||
EZBENCH2("ceil", donothing, _ceil(.7)); /* ~3ns */
|
||||
EZBENCH2("ceilf", donothing, _ceilf(.7)); /* ~3ns */
|
||||
EZBENCH2("ceill", donothing, _ceill(.7)); /* ~9ns */
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -54,3 +55,12 @@ TEST(exp2f, test) {
|
|||
EXPECT_STREQ("0", gc(xdtoaf(exp2f(-132098844872390))));
|
||||
EXPECT_STREQ("INFINITY", gc(xdtoaf(exp2f(132098844872390))));
|
||||
}
|
||||
|
||||
BENCH(exp2l, bench) {
|
||||
double _exp2(double) asm("exp2");
|
||||
float _exp2f(float) asm("exp2f");
|
||||
long double _exp2l(long double) asm("exp2l");
|
||||
EZBENCH2("exp2", donothing, _exp2(.7)); /* ~6ns */
|
||||
EZBENCH2("exp2f", donothing, _exp2f(.7)); /* ~5ns */
|
||||
EZBENCH2("exp2l", donothing, _exp2l(.7)); /* ~30ns */
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -61,3 +62,12 @@ TEST(exp, fun) {
|
|||
ASSERT_STREQ("6.389056", gc(xasprintf("%f", expm1(2.0))));
|
||||
ASSERT_STREQ("6.389056", gc(xasprintf("%f", exp(2.0) - 1.0)));
|
||||
}
|
||||
|
||||
BENCH(expl, bench) {
|
||||
double _exp(double) asm("exp");
|
||||
float _expf(float) asm("expf");
|
||||
long double _expl(long double) asm("expl");
|
||||
EZBENCH2("exp", donothing, _exp(.7)); /* ~6ns */
|
||||
EZBENCH2("expf", donothing, _expf(.7)); /* ~5ns */
|
||||
EZBENCH2("expl", donothing, _expl(.7)); /* ~20ns */
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -53,3 +54,12 @@ TEST(floorl, test) {
|
|||
EXPECT_STREQ("INFINITY", gc(xdtoal(floorl(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoal(floorl(-INFINITY))));
|
||||
}
|
||||
|
||||
BENCH(floorl, bench) {
|
||||
double _floor(double) asm("floor");
|
||||
float _floorf(float) asm("floorf");
|
||||
long double _floorl(long double) asm("floorl");
|
||||
EZBENCH2("floor", donothing, _floor(.7)); /* ~3ns */
|
||||
EZBENCH2("floorf", donothing, _floorf(.7)); /* ~3ns */
|
||||
EZBENCH2("floorl", donothing, _floorl(.7)); /* ~9ns */
|
||||
}
|
||||
|
|
66
test/libc/tinymath/log10_test.c
Normal file
66
test/libc/tinymath/log10_test.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
TEST(log10l, test) {
|
||||
EXPECT_STREQ("1", gc(xdtoal(log10l(10))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoal(log10l(NAN))));
|
||||
EXPECT_STREQ("0", gc(xdtoal(log10l(1))));
|
||||
EXPECT_STREQ("INFINITY", gc(xdtoal(log10l(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoal(log10l(0))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoal(log10l(-0.))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoal(log10l(-1))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoal(log10l(-2))));
|
||||
}
|
||||
|
||||
TEST(log10, test) {
|
||||
EXPECT_STREQ(".301029995663981", gc(xdtoa(log10(2))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(log10(100))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoa(log10(NAN))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(log10(1))));
|
||||
EXPECT_STREQ("INFINITY", gc(xdtoa(log10(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoa(log10(0))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoa(log10(-0.))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoa(log10(-1))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoa(log10(-2))));
|
||||
}
|
||||
|
||||
TEST(log10f, test) {
|
||||
EXPECT_STREQ("1", gc(xdtoaf(log10f(10))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoaf(log10f(NAN))));
|
||||
EXPECT_STREQ("0", gc(xdtoaf(log10f(1))));
|
||||
EXPECT_STREQ("INFINITY", gc(xdtoaf(log10f(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoaf(log10f(0))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoaf(log10f(-0.))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoaf(log10f(-1))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoaf(log10f(-2))));
|
||||
}
|
||||
|
||||
BENCH(log10, bench) {
|
||||
double _log10(double) asm("log10");
|
||||
float _log10f(float) asm("log10f");
|
||||
long double _log10l(long double) asm("log10l");
|
||||
EZBENCH2("log10", donothing, _log10(.7)); /* ~20ns */
|
||||
EZBENCH2("log10f", donothing, _log10f(.7)); /* ~21ns */
|
||||
EZBENCH2("log10l", donothing, _log10l(.7)); /* ~21ns */
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -54,3 +55,12 @@ TEST(log2f, test) {
|
|||
EXPECT_STREQ("-NAN", gc(xdtoaf(log2f(-1))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoaf(log2f(-2))));
|
||||
}
|
||||
|
||||
BENCH(log2, bench) {
|
||||
double _log2(double) asm("log2");
|
||||
float _log2f(float) asm("log2f");
|
||||
long double _log2l(long double) asm("log2l");
|
||||
EZBENCH2("log2", donothing, _log2(.7)); /* ~9ns */
|
||||
EZBENCH2("log2f", donothing, _log2f(.7)); /* ~6ns */
|
||||
EZBENCH2("log2l", donothing, _log2l(.7)); /* ~21ns */
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -54,3 +55,12 @@ TEST(logf, test) {
|
|||
EXPECT_STREQ("-NAN", gc(xdtoaf(logf(-1))));
|
||||
EXPECT_STREQ("-NAN", gc(xdtoaf(logf(-2))));
|
||||
}
|
||||
|
||||
BENCH(logl, bench) {
|
||||
double _log(double) asm("log");
|
||||
float _logf(float) asm("logf");
|
||||
long double _logl(long double) asm("logl");
|
||||
EZBENCH2("log", donothing, _log(.7)); /* ~9ns */
|
||||
EZBENCH2("logf", donothing, _logf(.7)); /* ~20ns */
|
||||
EZBENCH2("logl", donothing, _logl(.7)); /* ~20ns */
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ void SetUp(void) {
|
|||
rando = rand() & 0xffff;
|
||||
}
|
||||
|
||||
static double POW(double x, double y) {
|
||||
return powl(x, y);
|
||||
}
|
||||
|
||||
static char *fmtd(double x) {
|
||||
sprintf(buf, "%.15g", x);
|
||||
return buf;
|
||||
|
@ -209,356 +213,356 @@ TEST(powf, test) {
|
|||
}
|
||||
|
||||
TEST(powl, errors) {
|
||||
EXPECT_STREQ("1", fmtd(pow(0., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(0., -0.)));
|
||||
EXPECT_STREQ("0", fmtd(pow(0., .5)));
|
||||
EXPECT_STREQ("1", fmtd(POW(0., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(0., -0.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., .5)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(0., -.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(0., -.5)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_STREQ("0", fmtd(pow(0., 1.)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(0., -1.)));
|
||||
EXPECT_STREQ("0", fmtd(pow(0., 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., 1.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(0., -1.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., 1.5)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(0., -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(0., -1.5)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_STREQ("0", fmtd(pow(0., 2.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., 2.)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(0., -2.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(0., -2.)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_TRUE(isnan(pow(0., NAN)));
|
||||
EXPECT_TRUE(isnan(pow(0., -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(pow(0., INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(0., -INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(0., __DBL_MIN__)));
|
||||
EXPECT_STREQ("0", fmtd(pow(0., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-0., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-0., -0.)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., .5)));
|
||||
EXPECT_TRUE(isnan(POW(0., NAN)));
|
||||
EXPECT_TRUE(isnan(POW(0., -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(0., -INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., __DBL_MIN__)));
|
||||
EXPECT_STREQ("0", fmtd(POW(0., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-0., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-0., -0.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., .5)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(-0., -.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-0., -.5)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_STREQ("-0", fmtd(pow(-0., 1.)));
|
||||
EXPECT_STREQ("-inf", fmtd(pow(-0., -1.)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., 1.5)));
|
||||
EXPECT_STREQ("-0", fmtd(POW(-0., 1.)));
|
||||
EXPECT_STREQ("-inf", fmtd(POW(-0., -1.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., 1.5)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(-0., -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-0., -1.5)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., 2.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., 2.)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(-0., -2.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-0., -2.)));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
EXPECT_TRUE(isnan(pow(-0., NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-0., -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-0., -INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., __DBL_MIN__)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-0., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(.5, -0.)));
|
||||
EXPECT_STREQ("0.707106781186548", fmtd(pow(.5, .5)));
|
||||
EXPECT_STREQ("1.4142135623731", fmtd(pow(.5, -.5)));
|
||||
EXPECT_STREQ("0.5", fmtd(pow(.5, 1.)));
|
||||
EXPECT_STREQ("2", fmtd(pow(.5, -1.)));
|
||||
EXPECT_STREQ("0.353553390593274", fmtd(pow(.5, 1.5)));
|
||||
EXPECT_STREQ("2.82842712474619", fmtd(pow(.5, -1.5)));
|
||||
EXPECT_STREQ("0.25", fmtd(pow(.5, 2.)));
|
||||
EXPECT_STREQ("4", fmtd(pow(.5, -2.)));
|
||||
EXPECT_TRUE(isnan(pow(.5, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(.5, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(pow(.5, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(.5, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(.5, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-0., NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-0., -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-0., -INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., __DBL_MIN__)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-0., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(.5, -0.)));
|
||||
EXPECT_STREQ("0.707106781186548", fmtd(POW(.5, .5)));
|
||||
EXPECT_STREQ("1.4142135623731", fmtd(POW(.5, -.5)));
|
||||
EXPECT_STREQ("0.5", fmtd(POW(.5, 1.)));
|
||||
EXPECT_STREQ("2", fmtd(POW(.5, -1.)));
|
||||
EXPECT_STREQ("0.353553390593274", fmtd(POW(.5, 1.5)));
|
||||
EXPECT_STREQ("2.82842712474619", fmtd(POW(.5, -1.5)));
|
||||
EXPECT_STREQ("0.25", fmtd(POW(.5, 2.)));
|
||||
EXPECT_STREQ("4", fmtd(POW(.5, -2.)));
|
||||
EXPECT_TRUE(isnan(POW(.5, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(.5, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(POW(.5, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(.5, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(.5, __DBL_MIN__)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("0", fmtd(pow(.5, __DBL_MAX__)));
|
||||
EXPECT_STREQ("0", fmtd(POW(.5, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(-.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-.5, -0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-.5, -0.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-.5, .5)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, .5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-.5, -.5)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, -.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("-0.5", fmtd(pow(-.5, 1.)));
|
||||
EXPECT_STREQ("-2", fmtd(pow(-.5, -1.)));
|
||||
EXPECT_STREQ("-0.5", fmtd(POW(-.5, 1.)));
|
||||
EXPECT_STREQ("-2", fmtd(POW(-.5, -1.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-.5, 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, 1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-.5, -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, -1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("0.25", fmtd(pow(-.5, 2.)));
|
||||
EXPECT_STREQ("4", fmtd(pow(-.5, -2.)));
|
||||
EXPECT_TRUE(isnan(pow(-.5, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-.5, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-.5, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-.5, -INFINITY)));
|
||||
EXPECT_STREQ("0.25", fmtd(POW(-.5, 2.)));
|
||||
EXPECT_STREQ("4", fmtd(POW(-.5, -2.)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-.5, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-.5, -INFINITY)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-.5, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-.5, __DBL_MIN__)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_STREQ("0", fmtd(pow(-.5, __DBL_MAX__)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-.5, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(1., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., .5)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -.5)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., 1.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -1.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., 1.5)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -1.5)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., 2.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -2.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., NAN)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -NAN)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., __DBL_MIN__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., -0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., .5)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -.5)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., 1.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -1.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., 1.5)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -1.5)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., 2.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -2.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., NAN)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -NAN)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., __DBL_MIN__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., -0.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1., .5)));
|
||||
EXPECT_TRUE(isnan(POW(-1., .5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1., -.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1., -.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("-1", fmtd(pow(-1., 1.)));
|
||||
EXPECT_STREQ("-1", fmtd(pow(-1., -1.)));
|
||||
EXPECT_STREQ("-1", fmtd(POW(-1., 1.)));
|
||||
EXPECT_STREQ("-1", fmtd(POW(-1., -1.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1., 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1., 1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1., -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1., -1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., 2.0)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-1., NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-1., -NAN)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., 2.0)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-1., NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-1., -NAN)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., -INFINITY)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1., __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-1., __DBL_MIN__)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("1", fmtd(pow(-1., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1.5, -0.)));
|
||||
EXPECT_STREQ("1.22474487139159", fmtd(pow(1.5, .5)));
|
||||
EXPECT_STREQ("0.816496580927726", fmtd(pow(1.5, -.5)));
|
||||
EXPECT_STREQ("1.5", fmtd(pow(1.5, 1.)));
|
||||
EXPECT_STREQ("0.666666666666667", fmtd(pow(1.5, -1.)));
|
||||
EXPECT_STREQ("1.83711730708738", fmtd(pow(1.5, 1.5)));
|
||||
EXPECT_STREQ("0.544331053951817", fmtd(pow(1.5, -1.5)));
|
||||
EXPECT_STREQ("2.25", fmtd(pow(1.5, 2.0)));
|
||||
EXPECT_STREQ("0.444444444444444", fmtd(pow(1.5, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(1.5, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(1.5, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(1.5, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(1.5, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(1.5, __DBL_MIN__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1., __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1.5, -0.)));
|
||||
EXPECT_STREQ("1.22474487139159", fmtd(POW(1.5, .5)));
|
||||
EXPECT_STREQ("0.816496580927726", fmtd(POW(1.5, -.5)));
|
||||
EXPECT_STREQ("1.5", fmtd(POW(1.5, 1.)));
|
||||
EXPECT_STREQ("0.666666666666667", fmtd(POW(1.5, -1.)));
|
||||
EXPECT_STREQ("1.83711730708738", fmtd(POW(1.5, 1.5)));
|
||||
EXPECT_STREQ("0.544331053951817", fmtd(POW(1.5, -1.5)));
|
||||
EXPECT_STREQ("2.25", fmtd(POW(1.5, 2.0)));
|
||||
EXPECT_STREQ("0.444444444444444", fmtd(POW(1.5, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(1.5, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(1.5, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(1.5, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(1.5, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(1.5, __DBL_MIN__)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(1.5, __DBL_MAX__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(1.5, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(-1.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-1.5, -0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1.5, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-1.5, -0.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1.5, .5)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, .5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1.5, -.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, -.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("-1.5", fmtd(pow(-1.5, 1.)));
|
||||
EXPECT_STREQ("-0.666666666666667", fmtd(pow(-1.5, -1.)));
|
||||
EXPECT_STREQ("-1.5", fmtd(POW(-1.5, 1.)));
|
||||
EXPECT_STREQ("-0.666666666666667", fmtd(POW(-1.5, -1.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1.5, 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, 1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1.5, -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, -1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("2.25", fmtd(pow(-1.5, 2.0)));
|
||||
EXPECT_STREQ("0.444444444444444", fmtd(pow(-1.5, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-1.5, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-1.5, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-1.5, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-1.5, -INFINITY)));
|
||||
EXPECT_STREQ("2.25", fmtd(POW(-1.5, 2.0)));
|
||||
EXPECT_STREQ("0.444444444444444", fmtd(POW(-1.5, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-1.5, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-1.5, -INFINITY)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-1.5, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-1.5, __DBL_MIN__)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(-1.5, __DBL_MAX__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-1.5, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(+2.0, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(+2.0, -0.)));
|
||||
EXPECT_STREQ("1.4142135623731", fmtd(pow(+2.0, .5)));
|
||||
EXPECT_STREQ("0.707106781186548", fmtd(pow(+2.0, -.5)));
|
||||
EXPECT_STREQ("2", fmtd(pow(+2.0, 1.)));
|
||||
EXPECT_STREQ("0.5", fmtd(pow(+2.0, -1.)));
|
||||
EXPECT_STREQ("2.82842712474619", fmtd(pow(+2.0, 1.5)));
|
||||
EXPECT_STREQ("0.353553390593274", fmtd(pow(+2.0, -1.5)));
|
||||
EXPECT_STREQ("4", fmtd(pow(+2.0, 2.0)));
|
||||
EXPECT_STREQ("0.25", fmtd(pow(+2.0, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(+2.0, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(+2.0, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(+2.0, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(+2.0, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(+2.0, __DBL_MIN__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(+2.0, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(+2.0, -0.)));
|
||||
EXPECT_STREQ("1.4142135623731", fmtd(POW(+2.0, .5)));
|
||||
EXPECT_STREQ("0.707106781186548", fmtd(POW(+2.0, -.5)));
|
||||
EXPECT_STREQ("2", fmtd(POW(+2.0, 1.)));
|
||||
EXPECT_STREQ("0.5", fmtd(POW(+2.0, -1.)));
|
||||
EXPECT_STREQ("2.82842712474619", fmtd(POW(+2.0, 1.5)));
|
||||
EXPECT_STREQ("0.353553390593274", fmtd(POW(+2.0, -1.5)));
|
||||
EXPECT_STREQ("4", fmtd(POW(+2.0, 2.0)));
|
||||
EXPECT_STREQ("0.25", fmtd(POW(+2.0, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(+2.0, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(+2.0, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(+2.0, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(+2.0, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(+2.0, __DBL_MIN__)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(+2.0, __DBL_MAX__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(+2.0, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(-2.0, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-2.0, -0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-2.0, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-2.0, -0.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-2.0, .5)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, .5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-2.0, -.5)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, -.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("-2", fmtd(pow(-2.0, 1.)));
|
||||
EXPECT_STREQ("-0.5", fmtd(pow(-2.0, -1.)));
|
||||
EXPECT_STREQ("-2", fmtd(POW(-2.0, 1.)));
|
||||
EXPECT_STREQ("-0.5", fmtd(POW(-2.0, -1.)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-2.0, 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, 1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-2.0, -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, -1.5)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
EXPECT_STREQ("4", fmtd(pow(-2.0, 2.0)));
|
||||
EXPECT_STREQ("0.25", fmtd(pow(-2.0, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-2.0, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-2.0, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-2.0, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-2.0, -INFINITY)));
|
||||
EXPECT_STREQ("4", fmtd(POW(-2.0, 2.0)));
|
||||
EXPECT_STREQ("0.25", fmtd(POW(-2.0, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-2.0, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-2.0, -INFINITY)));
|
||||
errno = 0;
|
||||
EXPECT_TRUE(isnan(pow(-2.0, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-2.0, __DBL_MIN__)));
|
||||
EXPECT_EQ(EDOM, errno);
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(-2.0, __DBL_MAX__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-2.0, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(NAN, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(NAN, -0.)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, .5)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -.5)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, 1.)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -1.)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, 1.5)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -1.5)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, 2.0)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -NAN)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, INFINITY)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, -INFINITY)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(pow(NAN, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-NAN, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-NAN, -0.)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, .5)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -.5)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, 1.)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -1.)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, 1.5)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -1.5)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, 2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, INFINITY)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, -INFINITY)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(pow(-NAN, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(INFINITY, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(INFINITY, -0.)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, .5)));
|
||||
EXPECT_STREQ("0", fmtd(pow(INFINITY, -.5)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, 1.)));
|
||||
EXPECT_STREQ("0", fmtd(pow(INFINITY, -1.)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(pow(INFINITY, -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, 2.0)));
|
||||
EXPECT_STREQ("0", fmtd(pow(INFINITY, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(INFINITY, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(INFINITY, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(INFINITY, -INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, __DBL_MIN__)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(INFINITY, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-INFINITY, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(-INFINITY, -0.)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, .5)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-INFINITY, -.5)));
|
||||
EXPECT_STREQ("-inf", fmtd(pow(-INFINITY, 1.)));
|
||||
EXPECT_STREQ("-0", fmtd(pow(-INFINITY, -1.)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-INFINITY, -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, 2.0)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-INFINITY, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(-INFINITY, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(-INFINITY, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(-INFINITY, -INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, __DBL_MIN__)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(-INFINITY, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MIN__, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MIN__, -0.)));
|
||||
EXPECT_STREQ("1.49166814624004e-154", fmtd(pow(__DBL_MIN__, .5)));
|
||||
EXPECT_STREQ("6.7039039649713e+153", fmtd(pow(__DBL_MIN__, -.5)));
|
||||
EXPECT_STREQ("2.2250738585072e-308", fmtd(pow(__DBL_MIN__, 1.)));
|
||||
EXPECT_STREQ("4.49423283715579e+307", fmtd(pow(__DBL_MIN__, -1.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(NAN, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(NAN, -0.)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, .5)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -.5)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, 1.)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -1.)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, 2.0)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -NAN)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, INFINITY)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, -INFINITY)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(NAN, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-NAN, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-NAN, -0.)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, .5)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -.5)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, 1.)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -1.)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, 1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -1.5)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, 2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, INFINITY)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, -INFINITY)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(-NAN, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(INFINITY, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(INFINITY, -0.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, .5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(INFINITY, -.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, 1.)));
|
||||
EXPECT_STREQ("0", fmtd(POW(INFINITY, -1.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(INFINITY, -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, 2.0)));
|
||||
EXPECT_STREQ("0", fmtd(POW(INFINITY, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(INFINITY, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(INFINITY, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(INFINITY, -INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, __DBL_MIN__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(INFINITY, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-INFINITY, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(-INFINITY, -0.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, .5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-INFINITY, -.5)));
|
||||
EXPECT_STREQ("-inf", fmtd(POW(-INFINITY, 1.)));
|
||||
EXPECT_STREQ("-0", fmtd(POW(-INFINITY, -1.)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-INFINITY, -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, 2.0)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-INFINITY, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(-INFINITY, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(-INFINITY, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(-INFINITY, -INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, __DBL_MIN__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(-INFINITY, __DBL_MAX__)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MIN__, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MIN__, -0.)));
|
||||
EXPECT_STREQ("1.49166814624004e-154", fmtd(POW(__DBL_MIN__, .5)));
|
||||
EXPECT_STREQ("6.7039039649713e+153", fmtd(POW(__DBL_MIN__, -.5)));
|
||||
EXPECT_STREQ("2.2250738585072e-308", fmtd(POW(__DBL_MIN__, 1.)));
|
||||
EXPECT_STREQ("4.49423283715579e+307", fmtd(POW(__DBL_MIN__, -1.)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MIN__, 1.5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MIN__, 1.5)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MIN__, -1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MIN__, -1.5)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MIN__, 2.0)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MIN__, -2.0)));
|
||||
EXPECT_TRUE(isnan(pow(__DBL_MIN__, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(__DBL_MIN__, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MIN__, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MIN__, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MIN__, __DBL_MIN__)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MIN__, 2.0)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MIN__, -2.0)));
|
||||
EXPECT_TRUE(isnan(POW(__DBL_MIN__, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(__DBL_MIN__, -NAN)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MIN__, INFINITY)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MIN__, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MIN__, __DBL_MIN__)));
|
||||
/* errno = 0; */ /* wut */
|
||||
/* EXPECT_STREQ("0", fmtd(pow(__DBL_MIN__, __DBL_MAX__))); */
|
||||
/* EXPECT_STREQ("0", fmtd(POW(__DBL_MIN__, __DBL_MAX__))); */
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MAX__, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MAX__, -0.)));
|
||||
EXPECT_STREQ("1.34078079299426e+154", fmtd(pow(__DBL_MAX__, .5)));
|
||||
EXPECT_STREQ("7.45834073120021e-155", fmtd(pow(__DBL_MAX__, -.5)));
|
||||
EXPECT_STREQ("1.79769313486232e+308", fmtd(pow(__DBL_MAX__, 1.)));
|
||||
EXPECT_STREQ("5.562684646268e-309", fmtd(pow(__DBL_MAX__, -1.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MAX__, 0.)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MAX__, -0.)));
|
||||
EXPECT_STREQ("1.34078079299426e+154", fmtd(POW(__DBL_MAX__, .5)));
|
||||
EXPECT_STREQ("7.45834073120021e-155", fmtd(POW(__DBL_MAX__, -.5)));
|
||||
EXPECT_STREQ("1.79769313486232e+308", fmtd(POW(__DBL_MAX__, 1.)));
|
||||
EXPECT_STREQ("5.562684646268e-309", fmtd(POW(__DBL_MAX__, -1.)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MAX__, 1.5)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MAX__, 1.5)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
errno = 0;
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MAX__, -1.5)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MAX__, -1.5)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MAX__, 2.0)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MAX__, 2.0)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MAX__, -2.0)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MAX__, -2.0)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_TRUE(isnan(pow(__DBL_MAX__, NAN)));
|
||||
EXPECT_TRUE(isnan(pow(__DBL_MAX__, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MAX__, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(pow(__DBL_MAX__, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(pow(__DBL_MAX__, __DBL_MIN__)));
|
||||
EXPECT_TRUE(isnan(POW(__DBL_MAX__, NAN)));
|
||||
EXPECT_TRUE(isnan(POW(__DBL_MAX__, -NAN)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MAX__, INFINITY)));
|
||||
EXPECT_STREQ("0", fmtd(POW(__DBL_MAX__, -INFINITY)));
|
||||
EXPECT_STREQ("1", fmtd(POW(__DBL_MAX__, __DBL_MIN__)));
|
||||
errno = 0;
|
||||
EXPECT_STREQ("inf", fmtd(pow(__DBL_MAX__, __DBL_MAX__)));
|
||||
EXPECT_STREQ("inf", fmtd(POW(__DBL_MAX__, __DBL_MAX__)));
|
||||
/* EXPECT_EQ(ERANGE, errno); */
|
||||
EXPECT_STREQ("1", gc(xasprintf("%.15g", pow(0., 0))));
|
||||
EXPECT_STREQ("1", gc(xasprintf("%.15g", pow(-0., 0))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", pow(-0., 1))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", pow(-0., 11))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", pow(-0., 111))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", pow(-0., 2))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", pow(-0., 22))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", pow(-0., 222))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", pow(-0., 2.5))));
|
||||
EXPECT_STREQ("1", gc(xasprintf("%.15g", POW(0., 0))));
|
||||
EXPECT_STREQ("1", gc(xasprintf("%.15g", POW(-0., 0))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", POW(-0., 1))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", POW(-0., 11))));
|
||||
EXPECT_STREQ("-0", gc(xasprintf("%.15g", POW(-0., 111))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", POW(-0., 2))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", POW(-0., 22))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", POW(-0., 222))));
|
||||
EXPECT_STREQ("0", gc(xasprintf("%.15g", POW(-0., 2.5))));
|
||||
}
|
||||
|
||||
BENCH(powl, bench) {
|
||||
double _pow(double, double) asm("pow");
|
||||
float _powf(float, float) asm("powf");
|
||||
long double _powl(long double, long double) asm("powl");
|
||||
EZBENCH2("pow", donothing, _pow(.7, .2)); /* ~56ns */
|
||||
EZBENCH2("pow", donothing, _pow(.7, .2)); /* ~18ns */
|
||||
EZBENCH2("powf", donothing, _powf(.7, .2)); /* ~56ns */
|
||||
EZBENCH2("powl", donothing, _powl(.7, .2)); /* ~56ns */
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -53,3 +54,12 @@ TEST(truncl, test) {
|
|||
EXPECT_STREQ("INFINITY", gc(xdtoal(truncl(INFINITY))));
|
||||
EXPECT_STREQ("-INFINITY", gc(xdtoal(truncl(-INFINITY))));
|
||||
}
|
||||
|
||||
BENCH(truncl, bench) {
|
||||
double _trunc(double) asm("trunc");
|
||||
float _truncf(float) asm("truncf");
|
||||
long double _truncl(long double) asm("truncl");
|
||||
EZBENCH2("trunc", donothing, _trunc(.7)); /* ~2ns */
|
||||
EZBENCH2("truncf", donothing, _truncf(.7)); /* ~2ns */
|
||||
EZBENCH2("truncl", donothing, _truncl(.7)); /* ~9ns */
|
||||
}
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
"__builtin_infd64"
|
||||
"__builtin_infd128"
|
||||
"__builtin_inff"
|
||||
"__builtin_fma"
|
||||
"__builtin_infl"
|
||||
"__builtin_inffn"
|
||||
"__builtin_inffnx"
|
||||
|
|
Loading…
Add table
Reference in a new issue