mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 17:36:14 +00:00
[CRT:MATH] Import nextafter, nextafterf and nexttowardf from musl
Note: On Windows, where a long double is the same as a double, nextafterl is the same as nextafter, nexttowardl is the same as nexttoward. Also nexttoward is the same as nextafter.
This commit is contained in:
parent
5c26ccdb29
commit
a9ee20cb9a
12 changed files with 210 additions and 39 deletions
|
@ -236,7 +236,7 @@
|
|||
@ cdecl _mkdir(str)
|
||||
@ cdecl _mktemp(str)
|
||||
@ cdecl _msize(ptr)
|
||||
@ cdecl _nextafter(double double)
|
||||
@ cdecl _nextafter(double double) nextafter
|
||||
@ cdecl _onexit(ptr)
|
||||
@ varargs _open(str long)
|
||||
@ cdecl _open_osfhandle(long long)
|
||||
|
|
|
@ -882,8 +882,8 @@
|
|||
@ cdecl _mktime64(ptr)
|
||||
@ cdecl _msize(ptr)
|
||||
@ stub -version=0x600+ -arch=i386 _msize_debug
|
||||
@ cdecl _nextafter(double double)
|
||||
@ stub -arch=x86_64 _nextafterf
|
||||
@ cdecl _nextafter(double double) nextafter
|
||||
@ cdecl -arch=!i386 _nextafterf(long) nextafterf
|
||||
@ extern _onexit # Declaring it as extern let us use the symbol from msvcrtex while having the __imp_ symbol defined in the import lib
|
||||
@ varargs _open(str long)
|
||||
@ cdecl _open_osfhandle(long long)
|
||||
|
|
|
@ -739,7 +739,7 @@
|
|||
@ cdecl _msize(ptr)
|
||||
@ stub _mtlock
|
||||
@ stub _mtunlock
|
||||
@ cdecl _nextafter(double double)
|
||||
@ cdecl _nextafter(double double) nextafter
|
||||
@ cdecl _onexit(ptr)
|
||||
@ varargs _open(str long)
|
||||
@ cdecl _open_osfhandle(long long)
|
||||
|
|
|
@ -800,7 +800,7 @@
|
|||
@ cdecl _msize(ptr)
|
||||
@ stub _mtlock
|
||||
@ stub _mtunlock
|
||||
@ cdecl _nextafter(double double)
|
||||
@ cdecl _nextafter(double double) nextafter
|
||||
@ cdecl _onexit(ptr)
|
||||
@ varargs _open(str long)
|
||||
@ cdecl _open_osfhandle(long long)
|
||||
|
|
|
@ -1792,9 +1792,9 @@
|
|||
@ cdecl _o_nextafter(double double) nextafter
|
||||
@ cdecl _o_nextafterf(float float) nextafterf
|
||||
@ cdecl _o_nextafterl(double double) nextafter
|
||||
@ cdecl _o_nexttoward(double double) nexttoward
|
||||
@ cdecl _o_nexttoward(double double) nextafter
|
||||
@ cdecl _o_nexttowardf(float double) nexttowardf
|
||||
@ cdecl _o_nexttowardl(double double) nexttoward
|
||||
@ cdecl _o_nexttowardl(double double) nextafter
|
||||
@ cdecl _o_pow(double double) pow
|
||||
@ cdecl -arch=!i386 _o_powf(float float) powf
|
||||
@ cdecl _o_putc(long ptr) putc
|
||||
|
@ -2511,12 +2511,12 @@
|
|||
@ cdecl -stub nearbyint(double)
|
||||
@ cdecl -stub nearbyintf(float)
|
||||
@ cdecl nearbyintl(double) nearbyint
|
||||
@ cdecl -stub nextafter(double double)
|
||||
@ cdecl -stub nextafterf(float float)
|
||||
@ cdecl nextafter(double double)
|
||||
@ cdecl nextafterf(float float)
|
||||
@ cdecl nextafterl(double double) nextafter
|
||||
@ cdecl -stub nexttoward(double double) nexttoward
|
||||
@ cdecl -stub nexttowardf(float double) nexttowardf
|
||||
@ cdecl nexttowardl(double double) nexttoward
|
||||
@ cdecl nexttoward(double double) nextafter
|
||||
@ cdecl nexttowardf(float double)
|
||||
@ cdecl nexttowardl(double double) nextafter
|
||||
@ stub norm
|
||||
@ stub normf
|
||||
@ stub norml
|
||||
|
|
|
@ -6,7 +6,6 @@ list(APPEND CRT_FLOAT_SOURCE
|
|||
float/copysign.c
|
||||
float/fpclass.c
|
||||
float/fpecode.c
|
||||
float/nafter.c
|
||||
float/scalb.c
|
||||
)
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/sdk/crt/float/nafter.c
|
||||
* PURPOSE: Unknown
|
||||
* PROGRAMER: Unknown
|
||||
* UPDATE HISTORY:
|
||||
* 25/11/05: Added license header
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
double _nextafter( double x, double y )
|
||||
{
|
||||
WARN("This function is not implemented correctly\n");
|
||||
if ( x == y)
|
||||
return x;
|
||||
|
||||
if ( _isnan(x) || _isnan(y) )
|
||||
return x;
|
||||
|
||||
return x;
|
||||
}
|
70
sdk/lib/crt/math/libm.h
Normal file
70
sdk/lib/crt/math/libm.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// libm.h
|
||||
//
|
||||
// Partly imported from musl libc
|
||||
//
|
||||
// Support header for musl math code.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
// Define _STATIC_ASSERT for compatibility with legacy CRT headers
|
||||
#ifndef _STATIC_ASSERT
|
||||
#define _STATIC_ASSERT(expr) extern char (*__static_assert__(void)) [(expr) ? 1 : -1]
|
||||
#endif
|
||||
|
||||
// Make sure the sizes are correct
|
||||
_STATIC_ASSERT(sizeof(float) == 4);
|
||||
_STATIC_ASSERT(sizeof(double) == 8);
|
||||
_STATIC_ASSERT(sizeof(long double) == 8);
|
||||
|
||||
_Check_return_ int __cdecl _isnanf(_In_ float _X);
|
||||
#define isnan _isnan
|
||||
#define isnanf _isnanf
|
||||
|
||||
// musl has this in math.h
|
||||
static __inline uint32_t __FLOAT_BITS(float __f)
|
||||
{
|
||||
union {float __f; uint32_t __i;} __u;
|
||||
__u.__f = __f;
|
||||
return __u.__i;
|
||||
}
|
||||
|
||||
static __inline uint64_t __DOUBLE_BITS(double __f)
|
||||
{
|
||||
union {double __f; uint64_t __i;} __u;
|
||||
__u.__f = __f;
|
||||
return __u.__i;
|
||||
}
|
||||
|
||||
#define signbit(x) \
|
||||
((sizeof(x) == sizeof(float)) ? (int)(__FLOAT_BITS(x)>>31) : \
|
||||
(int)(__DOUBLE_BITS(x)>>63))
|
||||
|
||||
static inline void fp_force_evalf(float x)
|
||||
{
|
||||
volatile float y;
|
||||
y = x;
|
||||
(void)y;
|
||||
}
|
||||
|
||||
static inline void fp_force_eval(double x)
|
||||
{
|
||||
volatile double y;
|
||||
y = x;
|
||||
(void)y;
|
||||
}
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
fp_force_evalf(x); \
|
||||
} else { \
|
||||
fp_force_eval(x); \
|
||||
} \
|
||||
} while(0)
|
|
@ -14,6 +14,9 @@ list(APPEND LIBCNTPR_MATH_SOURCE
|
|||
math/div.c
|
||||
math/exp2f.c
|
||||
math/labs.c
|
||||
math/nextafter.c
|
||||
math/nextafterf.c
|
||||
math/nexttowardf.c
|
||||
math/round.c
|
||||
math/roundf.c
|
||||
math/scalbn.c
|
||||
|
|
41
sdk/lib/crt/math/nextafter.c
Normal file
41
sdk/lib/crt/math/nextafter.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of nextafter.
|
||||
* COPYRIGHT: Imported from musl libc
|
||||
* https://git.musl-libc.org/cgit/musl/tree/src/math/nextafter.c
|
||||
* blob: ab5795a47a93e36c8c461d8a4be6621b582ae077
|
||||
* See https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
double nextafter(double x, double y)
|
||||
{
|
||||
union {double f; uint64_t i;} ux={x}, uy={y};
|
||||
uint64_t ax, ay;
|
||||
int e;
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return x + y;
|
||||
if (ux.i == uy.i)
|
||||
return y;
|
||||
ax = ux.i & ~0ULL/2;
|
||||
ay = uy.i & ~0ULL/2;
|
||||
if (ax == 0) {
|
||||
if (ay == 0)
|
||||
return y;
|
||||
ux.i = (uy.i & 1ULL<<63) | 1;
|
||||
} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
|
||||
ux.i--;
|
||||
else
|
||||
ux.i++;
|
||||
e = ux.i >> 52 & 0x7ff;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7ff)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
40
sdk/lib/crt/math/nextafterf.c
Normal file
40
sdk/lib/crt/math/nextafterf.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of nextafterf.
|
||||
* COPYRIGHT: Imported from musl libc
|
||||
* https://git.musl-libc.org/cgit/musl/tree/src/math/nextafterf.c
|
||||
* blob: 75a09f7d1cf115d9a5d5dfeda9b12d42de269904
|
||||
* See https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
float nextafterf(float x, float y)
|
||||
{
|
||||
union {float f; uint32_t i;} ux={x}, uy={y};
|
||||
uint32_t ax, ay, e;
|
||||
|
||||
if (isnanf(x) || isnanf(y))
|
||||
return x + y;
|
||||
if (ux.i == uy.i)
|
||||
return y;
|
||||
ax = ux.i & 0x7fffffff;
|
||||
ay = uy.i & 0x7fffffff;
|
||||
if (ax == 0) {
|
||||
if (ay == 0)
|
||||
return y;
|
||||
ux.i = (uy.i & 0x80000000) | 1;
|
||||
} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
|
||||
ux.i--;
|
||||
else
|
||||
ux.i++;
|
||||
e = ux.i & 0x7f800000;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7f800000)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
44
sdk/lib/crt/math/nexttowardf.c
Normal file
44
sdk/lib/crt/math/nexttowardf.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of scalbn.
|
||||
* COPYRIGHT: Imported from musl nexttowardf
|
||||
* https://git.musl-libc.org/cgit/musl/tree/src/math/nexttowardf.c
|
||||
* blob: bbf172f9e65573e9059d26ea574aa8a96dfdef43
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
float nexttowardf(float x, long double y)
|
||||
{
|
||||
union {float f; uint32_t i;} ux = {x};
|
||||
uint32_t e;
|
||||
|
||||
if (_isnan(x) || _isnan(y))
|
||||
return x + y;
|
||||
if (x == y)
|
||||
return y;
|
||||
if (x == 0) {
|
||||
ux.i = 1;
|
||||
if (signbit(y))
|
||||
ux.i |= 0x80000000;
|
||||
} else if (x < y) {
|
||||
if (signbit(x))
|
||||
ux.i--;
|
||||
else
|
||||
ux.i++;
|
||||
} else {
|
||||
if (signbit(x))
|
||||
ux.i++;
|
||||
else
|
||||
ux.i--;
|
||||
}
|
||||
e = ux.i & 0x7f800000;
|
||||
/* raise overflow if ux.f is infinite and x is finite */
|
||||
if (e == 0x7f800000)
|
||||
FORCE_EVAL(x+x);
|
||||
/* raise underflow if ux.f is subnormal or zero */
|
||||
if (e == 0)
|
||||
FORCE_EVAL(x*x + ux.f*ux.f);
|
||||
return ux.f;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue