Added SDL_nextafter() and SDL_nextafterf()

This commit is contained in:
Sam Lantinga
2023-06-13 07:34:50 -07:00
parent b0677f476f
commit bc5d074818
20 changed files with 319 additions and 47 deletions

View File

@@ -866,6 +866,8 @@ SDL3_0.0.0 {
SDL_hid_get_report_descriptor;
SDL_HasWindowSurface;
SDL_DestroyWindowSurface;
SDL_nextafter;
SDL_nextafterf;
# extra symbols go here (don't modify this line)
local: *;
};

View File

@@ -892,3 +892,5 @@
#define SDL_hid_get_report_descriptor SDL_hid_get_report_descriptor_REAL
#define SDL_HasWindowSurface SDL_HasWindowSurface_REAL
#define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL
#define SDL_nextafter SDL_nextafter_REAL
#define SDL_nextafterf SDL_nextafterf_REAL

View File

@@ -937,3 +937,5 @@ SDL_DYNAPI_PROC(SDL_hid_device_info*,SDL_hid_get_device_info,(SDL_hid_device *a)
SDL_DYNAPI_PROC(int,SDL_hid_get_report_descriptor,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasWindowSurface,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(double,SDL_nextafter,(double a, double b),(a,b),return)
SDL_DYNAPI_PROC(float,SDL_nextafterf,(float a, float b),(a,b),return)

View File

@@ -37,6 +37,8 @@ double SDL_uclibc_fmod(double x, double y);
double SDL_uclibc_log(double x);
double SDL_uclibc_log10(double x);
double SDL_uclibc_modf(double x, double *y);
double SDL_uclibc_nextafter(double from, double to);
float SDL_uclibc_nextafterf(float from, float to);
double SDL_uclibc_pow(double x, double y);
double SDL_uclibc_scalbn(double x, int n);
double SDL_uclibc_sin(double x);

View File

@@ -41,6 +41,8 @@ typedef unsigned int u_int32_t;
#define __ieee754_log SDL_uclibc_log
#define __ieee754_log10 SDL_uclibc_log10
#define modf SDL_uclibc_modf
#define nextafter SDL_uclibc_nextafter
#define nextafterf SDL_uclibc_nextafterf
#define __ieee754_pow SDL_uclibc_pow
#define scalbln SDL_uclibc_scalbln
#define scalbn SDL_uclibc_scalbn
@@ -225,4 +227,7 @@ __ieee754_sqrt(double)
extern int32_t __kernel_rem_pio2(const double *, double *, int, int, const unsigned int,
const int32_t *) attribute_hidden;
/* FIXME: We don't have a cross-platform implementation of this */
#define math_force_eval(x) (void)x
#endif /* _MATH_PRIVATE_H_ */

71
src/libm/s_nextafter.c Normal file
View File

@@ -0,0 +1,71 @@
#include "SDL_internal.h"
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* IEEE functions
* nextafter(x,y)
* return the next machine floating-point number of x in the
* direction toward y.
* Special cases:
*/
#include "math.h"
#include "math_private.h"
double nextafter(double x, double y)
{
int32_t hx,hy,ix,iy;
u_int32_t lx,ly;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
ix = hx&0x7fffffff; /* |x| */
iy = hy&0x7fffffff; /* |y| */
if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */
y = x*x;
if(y==x) return y; else return x; /* raise underflow flag */
}
if(hx>=0) { /* x > 0 */
if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
if(lx==0) hx -= 1;
lx -= 1;
} else { /* x < y, x += ulp */
lx += 1;
if(lx==0) hx += 1;
}
} else { /* x < 0 */
if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
if(lx==0) hx -= 1;
lx -= 1;
} else { /* x > y, x += ulp */
lx += 1;
if(lx==0) hx += 1;
}
}
hy = hx&0x7ff00000;
if(hy>=0x7ff00000) return x+x; /* overflow */
if(hy<0x00100000) { /* underflow */
y = x*x;
if(y!=x) { /* raise underflow flag */
INSERT_WORDS(y,hx,lx);
return y;
}
}
INSERT_WORDS(x,hx,lx);
return x;
}
libm_hidden_def(nextafter)

97
src/libm/s_nextafterf.c Normal file
View File

@@ -0,0 +1,97 @@
#include "SDL_internal.h"
/* s_nextafterf.c -- float version of s_nextafter.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "math.h"
#include "math_private.h"
float nextafterf(float x, float y)
{
int32_t hx, hy, ix, iy;
GET_FLOAT_WORD(hx, x);
GET_FLOAT_WORD(hy, y);
ix = hx & 0x7fffffff; /* |x| */
iy = hy & 0x7fffffff; /* |y| */
/* x is nan or y is nan? */
if ((ix > 0x7f800000) || (iy > 0x7f800000))
return x + y;
if (x == y)
return y;
if (ix == 0) { /* x == 0? */
/* glibc 2.4 does not seem to set underflow? */
/* float u; */
/* return +-minsubnormal */
SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);
/* u = x * x; raise underflow flag */
/* math_force_eval(u); */
return x;
}
if (hx >= 0) { /* x > 0 */
if (hx > hy) { /* x > y: x -= ulp */
hx -= 1;
} else { /* x < y: x += ulp */
hx += 1;
}
} else { /* x < 0 */
if (hy >= 0 || hx > hy) { /* x < y: x -= ulp */
hx -= 1;
} else { /* x > y: x += ulp */
hx += 1;
}
}
hy = hx & 0x7f800000;
if (hy >= 0x7f800000) {
x = x + x; /* overflow */
return x; /* overflow */
}
if (hy < 0x00800000) {
float u = x * x; /* underflow */
math_force_eval(u); /* raise underflow flag */
}
SET_FLOAT_WORD(x, hx);
return x;
}
#if 0
/* "testprog N a b"
* calculates a = nextafterf(a, b) and prints a as float
* and as raw bytes; repeats it N times.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
int cnt, i;
float a, b;
cnt = atoi(argv[1]);
a = strtod(argv[2], NULL);
b = strtod(argv[3], NULL);
while (cnt-- > 0) {
for (i = 0; i < sizeof(a); i++) {
unsigned char c = ((char*)(&a))[i];
printf("%x%x", (c >> 4), (c & 0xf));
}
printf(" %f\n", a);
a = nextafterf(a, b);
}
return 0;
}
#endif

View File

@@ -24,8 +24,7 @@
#include "../libm/math_libm.h"
double
SDL_atan(double x)
double SDL_atan(double x)
{
#ifdef HAVE_ATAN
return atan(x);
@@ -43,8 +42,7 @@ float SDL_atanf(float x)
#endif
}
double
SDL_atan2(double y, double x)
double SDL_atan2(double y, double x)
{
#ifdef HAVE_ATAN2
return atan2(y, x);
@@ -62,8 +60,7 @@ float SDL_atan2f(float y, float x)
#endif
}
double
SDL_acos(double val)
double SDL_acos(double val)
{
#ifdef HAVE_ACOS
return acos(val);
@@ -90,8 +87,7 @@ float SDL_acosf(float val)
#endif
}
double
SDL_asin(double val)
double SDL_asin(double val)
{
#ifdef HAVE_ASIN
return asin(val);
@@ -115,8 +111,7 @@ float SDL_asinf(float val)
#endif
}
double
SDL_ceil(double x)
double SDL_ceil(double x)
{
#ifdef HAVE_CEIL
return ceil(x);
@@ -139,8 +134,7 @@ float SDL_ceilf(float x)
#endif
}
double
SDL_copysign(double x, double y)
double SDL_copysign(double x, double y)
{
#ifdef HAVE_COPYSIGN
return copysign(x, y);
@@ -166,8 +160,7 @@ float SDL_copysignf(float x, float y)
#endif
}
double
SDL_cos(double x)
double SDL_cos(double x)
{
#ifdef HAVE_COS
return cos(x);
@@ -185,8 +178,7 @@ float SDL_cosf(float x)
#endif
}
double
SDL_exp(double x)
double SDL_exp(double x)
{
#ifdef HAVE_EXP
return exp(x);
@@ -204,8 +196,7 @@ float SDL_expf(float x)
#endif
}
double
SDL_fabs(double x)
double SDL_fabs(double x)
{
#ifdef HAVE_FABS
return fabs(x);
@@ -223,8 +214,7 @@ float SDL_fabsf(float x)
#endif
}
double
SDL_floor(double x)
double SDL_floor(double x)
{
#ifdef HAVE_FLOOR
return floor(x);
@@ -242,8 +232,7 @@ float SDL_floorf(float x)
#endif
}
double
SDL_trunc(double x)
double SDL_trunc(double x)
{
#ifdef HAVE_TRUNC
return trunc(x);
@@ -265,8 +254,7 @@ float SDL_truncf(float x)
#endif
}
double
SDL_fmod(double x, double y)
double SDL_fmod(double x, double y)
{
#ifdef HAVE_FMOD
return fmod(x, y);
@@ -284,8 +272,7 @@ float SDL_fmodf(float x, float y)
#endif
}
double
SDL_log(double x)
double SDL_log(double x)
{
#ifdef HAVE_LOG
return log(x);
@@ -303,8 +290,7 @@ float SDL_logf(float x)
#endif
}
double
SDL_log10(double x)
double SDL_log10(double x)
{
#ifdef HAVE_LOG10
return log10(x);
@@ -322,8 +308,7 @@ float SDL_log10f(float x)
#endif
}
double
SDL_modf(double x, double *y)
double SDL_modf(double x, double *y)
{
#ifdef HAVE_MODF
return modf(x, y);
@@ -344,8 +329,25 @@ float SDL_modff(float x, float *y)
#endif
}
double
SDL_pow(double x, double y)
double SDL_nextafter(double from, double to)
{
#ifdef HAVE_NEXTAFTER
return nextafter(from, to);
#else
return SDL_uclibc_nextafter(from, to);
#endif
}
float SDL_nextafterf(float from, float to)
{
#ifdef HAVE_NEXTAFTERF
return nextafterf(from, to);
#else
return SDL_uclibc_nextafterf(from, to);
#endif
}
double SDL_pow(double x, double y)
{
#ifdef HAVE_POW
return pow(x, y);
@@ -363,8 +365,7 @@ float SDL_powf(float x, float y)
#endif
}
double
SDL_round(double arg)
double SDL_round(double arg)
{
#if defined HAVE_ROUND
return round(arg);
@@ -404,8 +405,7 @@ long SDL_lroundf(float arg)
#endif
}
double
SDL_scalbn(double x, int n)
double SDL_scalbn(double x, int n)
{
#ifdef HAVE_SCALBN
return scalbn(x, n);
@@ -429,8 +429,7 @@ float SDL_scalbnf(float x, int n)
#endif
}
double
SDL_sin(double x)
double SDL_sin(double x)
{
#ifdef HAVE_SIN
return sin(x);
@@ -448,8 +447,7 @@ float SDL_sinf(float x)
#endif
}
double
SDL_sqrt(double x)
double SDL_sqrt(double x)
{
#ifdef HAVE_SQRT
return sqrt(x);
@@ -467,8 +465,7 @@ float SDL_sqrtf(float x)
#endif
}
double
SDL_tan(double x)
double SDL_tan(double x)
{
#ifdef HAVE_TAN
return tan(x);