Skip to content

Commit a9ee20c

Browse files
committed
[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.
1 parent 5c26ccd commit a9ee20c

File tree

12 files changed

+210
-39
lines changed

12 files changed

+210
-39
lines changed

dll/win32/crtdll/crtdll.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@
236236
@ cdecl _mkdir(str)
237237
@ cdecl _mktemp(str)
238238
@ cdecl _msize(ptr)
239-
@ cdecl _nextafter(double double)
239+
@ cdecl _nextafter(double double) nextafter
240240
@ cdecl _onexit(ptr)
241241
@ varargs _open(str long)
242242
@ cdecl _open_osfhandle(long long)

dll/win32/msvcrt/msvcrt.spec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,8 +882,8 @@
882882
@ cdecl _mktime64(ptr)
883883
@ cdecl _msize(ptr)
884884
@ stub -version=0x600+ -arch=i386 _msize_debug
885-
@ cdecl _nextafter(double double)
886-
@ stub -arch=x86_64 _nextafterf
885+
@ cdecl _nextafter(double double) nextafter
886+
@ cdecl -arch=!i386 _nextafterf(long) nextafterf
887887
@ extern _onexit # Declaring it as extern let us use the symbol from msvcrtex while having the __imp_ symbol defined in the import lib
888888
@ varargs _open(str long)
889889
@ cdecl _open_osfhandle(long long)

dll/win32/msvcrt20/msvcrt20.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@
739739
@ cdecl _msize(ptr)
740740
@ stub _mtlock
741741
@ stub _mtunlock
742-
@ cdecl _nextafter(double double)
742+
@ cdecl _nextafter(double double) nextafter
743743
@ cdecl _onexit(ptr)
744744
@ varargs _open(str long)
745745
@ cdecl _open_osfhandle(long long)

dll/win32/msvcrt40/msvcrt40.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@
800800
@ cdecl _msize(ptr)
801801
@ stub _mtlock
802802
@ stub _mtunlock
803-
@ cdecl _nextafter(double double)
803+
@ cdecl _nextafter(double double) nextafter
804804
@ cdecl _onexit(ptr)
805805
@ varargs _open(str long)
806806
@ cdecl _open_osfhandle(long long)

dll/win32/ucrtbase/ucrtbase.spec

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,9 +1792,9 @@
17921792
@ cdecl _o_nextafter(double double) nextafter
17931793
@ cdecl _o_nextafterf(float float) nextafterf
17941794
@ cdecl _o_nextafterl(double double) nextafter
1795-
@ cdecl _o_nexttoward(double double) nexttoward
1795+
@ cdecl _o_nexttoward(double double) nextafter
17961796
@ cdecl _o_nexttowardf(float double) nexttowardf
1797-
@ cdecl _o_nexttowardl(double double) nexttoward
1797+
@ cdecl _o_nexttowardl(double double) nextafter
17981798
@ cdecl _o_pow(double double) pow
17991799
@ cdecl -arch=!i386 _o_powf(float float) powf
18001800
@ cdecl _o_putc(long ptr) putc
@@ -2511,12 +2511,12 @@
25112511
@ cdecl -stub nearbyint(double)
25122512
@ cdecl -stub nearbyintf(float)
25132513
@ cdecl nearbyintl(double) nearbyint
2514-
@ cdecl -stub nextafter(double double)
2515-
@ cdecl -stub nextafterf(float float)
2514+
@ cdecl nextafter(double double)
2515+
@ cdecl nextafterf(float float)
25162516
@ cdecl nextafterl(double double) nextafter
2517-
@ cdecl -stub nexttoward(double double) nexttoward
2518-
@ cdecl -stub nexttowardf(float double) nexttowardf
2519-
@ cdecl nexttowardl(double double) nexttoward
2517+
@ cdecl nexttoward(double double) nextafter
2518+
@ cdecl nexttowardf(float double)
2519+
@ cdecl nexttowardl(double double) nextafter
25202520
@ stub norm
25212521
@ stub normf
25222522
@ stub norml

sdk/lib/crt/float/float.cmake

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ list(APPEND CRT_FLOAT_SOURCE
66
float/copysign.c
77
float/fpclass.c
88
float/fpecode.c
9-
float/nafter.c
109
float/scalb.c
1110
)
1211

sdk/lib/crt/float/nafter.c

Lines changed: 0 additions & 26 deletions
This file was deleted.

sdk/lib/crt/math/libm.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//
2+
// libm.h
3+
//
4+
// Partly imported from musl libc
5+
//
6+
// Support header for musl math code.
7+
//
8+
// SPDX-License-Identifier: MIT
9+
//
10+
11+
#pragma once
12+
13+
#include <stdint.h>
14+
#include <float.h>
15+
#include <math.h>
16+
17+
// Define _STATIC_ASSERT for compatibility with legacy CRT headers
18+
#ifndef _STATIC_ASSERT
19+
#define _STATIC_ASSERT(expr) extern char (*__static_assert__(void)) [(expr) ? 1 : -1]
20+
#endif
21+
22+
// Make sure the sizes are correct
23+
_STATIC_ASSERT(sizeof(float) == 4);
24+
_STATIC_ASSERT(sizeof(double) == 8);
25+
_STATIC_ASSERT(sizeof(long double) == 8);
26+
27+
_Check_return_ int __cdecl _isnanf(_In_ float _X);
28+
#define isnan _isnan
29+
#define isnanf _isnanf
30+
31+
// musl has this in math.h
32+
static __inline uint32_t __FLOAT_BITS(float __f)
33+
{
34+
union {float __f; uint32_t __i;} __u;
35+
__u.__f = __f;
36+
return __u.__i;
37+
}
38+
39+
static __inline uint64_t __DOUBLE_BITS(double __f)
40+
{
41+
union {double __f; uint64_t __i;} __u;
42+
__u.__f = __f;
43+
return __u.__i;
44+
}
45+
46+
#define signbit(x) \
47+
((sizeof(x) == sizeof(float)) ? (int)(__FLOAT_BITS(x)>>31) : \
48+
(int)(__DOUBLE_BITS(x)>>63))
49+
50+
static inline void fp_force_evalf(float x)
51+
{
52+
volatile float y;
53+
y = x;
54+
(void)y;
55+
}
56+
57+
static inline void fp_force_eval(double x)
58+
{
59+
volatile double y;
60+
y = x;
61+
(void)y;
62+
}
63+
64+
#define FORCE_EVAL(x) do { \
65+
if (sizeof(x) == sizeof(float)) { \
66+
fp_force_evalf(x); \
67+
} else { \
68+
fp_force_eval(x); \
69+
} \
70+
} while(0)

sdk/lib/crt/math/math.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ list(APPEND LIBCNTPR_MATH_SOURCE
1414
math/div.c
1515
math/exp2f.c
1616
math/labs.c
17+
math/nextafter.c
18+
math/nextafterf.c
19+
math/nexttowardf.c
1720
math/round.c
1821
math/roundf.c
1922
math/scalbn.c

sdk/lib/crt/math/nextafter.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* PROJECT: ReactOS CRT
3+
* LICENSE: MIT (https://spdx.org/licenses/MIT)
4+
* PURPOSE: Implementation of nextafter.
5+
* COPYRIGHT: Imported from musl libc
6+
* https://git.musl-libc.org/cgit/musl/tree/src/math/nextafter.c
7+
* blob: ab5795a47a93e36c8c461d8a4be6621b582ae077
8+
* See https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
9+
*/
10+
11+
#include "libm.h"
12+
13+
double nextafter(double x, double y)
14+
{
15+
union {double f; uint64_t i;} ux={x}, uy={y};
16+
uint64_t ax, ay;
17+
int e;
18+
19+
if (isnan(x) || isnan(y))
20+
return x + y;
21+
if (ux.i == uy.i)
22+
return y;
23+
ax = ux.i & ~0ULL/2;
24+
ay = uy.i & ~0ULL/2;
25+
if (ax == 0) {
26+
if (ay == 0)
27+
return y;
28+
ux.i = (uy.i & 1ULL<<63) | 1;
29+
} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
30+
ux.i--;
31+
else
32+
ux.i++;
33+
e = ux.i >> 52 & 0x7ff;
34+
/* raise overflow if ux.f is infinite and x is finite */
35+
if (e == 0x7ff)
36+
FORCE_EVAL(x+x);
37+
/* raise underflow if ux.f is subnormal or zero */
38+
if (e == 0)
39+
FORCE_EVAL(x*x + ux.f*ux.f);
40+
return ux.f;
41+
}

0 commit comments

Comments
 (0)