SDL: Added SDL_isinf(), SDL_isinff(), SDL_isnan(), and SDL_isnanf()

From 89cdadf7c3364617059ea5298ace6ab3b5a3a20d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 24 Jun 2024 09:39:53 -0700
Subject: [PATCH] Added SDL_isinf(), SDL_isinff(), SDL_isnan(), and
 SDL_isnanf()

---
 CMakeLists.txt                                |  2 +-
 VisualC-GDK/SDL/SDL.vcxproj                   |  4 +
 VisualC-GDK/SDL/SDL.vcxproj.filters           |  4 +
 VisualC/SDL/SDL.vcxproj                       |  4 +
 VisualC/SDL/SDL.vcxproj.filters               | 12 +++
 Xcode/SDL/SDL.xcodeproj/project.pbxproj       | 20 +++++
 include/SDL3/SDL_stdinc.h                     | 56 +++++++++++++
 include/build_config/SDL_build_config.h.cmake |  4 +
 .../build_config/SDL_build_config_android.h   |  4 +
 include/build_config/SDL_build_config_ios.h   |  4 +
 include/build_config/SDL_build_config_macos.h |  4 +
 .../build_config/SDL_build_config_windows.h   |  4 +
 .../build_config/SDL_build_config_wingdk.h    |  4 +
 include/build_config/SDL_build_config_winrt.h |  4 +
 include/build_config/SDL_build_config_xbox.h  |  4 +
 src/dynapi/SDL_dynapi.sym                     |  4 +
 src/dynapi/SDL_dynapi_overrides.h             |  4 +
 src/dynapi/SDL_dynapi_procs.h                 |  4 +
 src/libm/math_libm.h                          | 36 +++++----
 src/libm/math_private.h                       | 78 ++++++++++---------
 src/libm/s_isinf.c                            | 24 ++++++
 src/libm/s_isinff.c                           | 24 ++++++
 src/libm/s_isnan.c                            | 31 ++++++++
 src/libm/s_isnanf.c                           | 33 ++++++++
 src/stdlib/SDL_stdlib.c                       | 40 ++++++++++
 25 files changed, 359 insertions(+), 53 deletions(-)
 create mode 100644 src/libm/s_isinf.c
 create mode 100644 src/libm/s_isinff.c
 create mode 100644 src/libm/s_isnan.c
 create mode 100644 src/libm/s_isnanf.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ddb476c841ca..3f5f3d5020a1e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1064,7 +1064,7 @@ if(SDL_LIBC)
     _Exit exp expf
     fabs fabsf floor floorf fmod fmodf fopen64 free fseeko fseeko64
     getenv
-    _i64toa index itoa
+    _i64toa index isinf isinff isnan isnanf itoa
     log log10 log10f logf lround lroundf _ltoa
     malloc memcmp memcpy memmove memset modf modff
     pow powf putenv
diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 82a5aaae01495..4c0c080532988 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -724,6 +724,10 @@
     <ClCompile Include="..\..\src\libm\s_cos.c" />
     <ClCompile Include="..\..\src\libm\s_fabs.c" />
     <ClCompile Include="..\..\src\libm\s_floor.c" />
+    <ClCompile Include="..\..\src\libm\s_isinf.c" />
+    <ClCompile Include="..\..\src\libm\s_isinff.c" />
+    <ClCompile Include="..\..\src\libm\s_isnan.c" />
+    <ClCompile Include="..\..\src\libm\s_isnanf.c" />
     <ClCompile Include="..\..\src\libm\s_modf.c" />
     <ClCompile Include="..\..\src\libm\s_scalbn.c" />
     <ClCompile Include="..\..\src\libm\s_sin.c" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 91684485f4fa2..5be93eef16972 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -106,6 +106,10 @@
     <ClCompile Include="..\..\src\libm\s_cos.c" />
     <ClCompile Include="..\..\src\libm\s_fabs.c" />
     <ClCompile Include="..\..\src\libm\s_floor.c" />
+    <ClCompile Include="..\..\src\libm\s_isinf.c" />
+    <ClCompile Include="..\..\src\libm\s_isinff.c" />
+    <ClCompile Include="..\..\src\libm\s_isnan.c" />
+    <ClCompile Include="..\..\src\libm\s_isnanf.c" />
     <ClCompile Include="..\..\src\libm\s_modf.c" />
     <ClCompile Include="..\..\src\libm\s_scalbn.c" />
     <ClCompile Include="..\..\src\libm\s_sin.c" />
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index a9849a3a53957..07f1fa70c4708 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -584,6 +584,10 @@
     <ClCompile Include="..\..\src\libm\s_cos.c" />
     <ClCompile Include="..\..\src\libm\s_fabs.c" />
     <ClCompile Include="..\..\src\libm\s_floor.c" />
+    <ClCompile Include="..\..\src\libm\s_isinf.c" />
+    <ClCompile Include="..\..\src\libm\s_isinff.c" />
+    <ClCompile Include="..\..\src\libm\s_isnan.c" />
+    <ClCompile Include="..\..\src\libm\s_isnanf.c" />
     <ClCompile Include="..\..\src\libm\s_modf.c" />
     <ClCompile Include="..\..\src\libm\s_scalbn.c" />
     <ClCompile Include="..\..\src\libm\s_sin.c" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 448bf3e4e49a5..a58186a588515 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -1096,6 +1096,18 @@
     <ClCompile Include="..\..\src\libm\s_floor.c">
       <Filter>libm</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\libm\s_isinf.c">
+      <Filter>libm</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libm\s_isinff.c">
+      <Filter>libm</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libm\s_isnan.c">
+      <Filter>libm</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\libm\s_isnanf.c">
+      <Filter>libm</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\libm\s_modf.c">
       <Filter>libm</Filter>
     </ClCompile>
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index 43ebab04d0429..aace663af0e5e 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -450,6 +450,11 @@
 		F3E5A6EB2AD5E0E600293D83 /* SDL_properties.c in Sources */ = {isa = PBXBuildFile; fileRef = F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */; };
 		F3E5A6ED2AD5E10800293D83 /* SDL_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = F3E5A6EC2AD5E10800293D83 /* SDL_properties.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; };
+		F3F528CB2C29E1C300E6CC26 /* s_isnanf.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F528C62C29E1C300E6CC26 /* s_isnanf.c */; };
+		F3F528CC2C29E1C300E6CC26 /* s_isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F528C72C29E1C300E6CC26 /* s_isinf.c */; };
+		F3F528CD2C29E1C300E6CC26 /* s_isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F528C82C29E1C300E6CC26 /* s_isnan.c */; };
+		F3F528CE2C29E1C300E6CC26 /* s_modf.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F528C92C29E1C300E6CC26 /* s_modf.c */; };
+		F3F528CF2C29E1C300E6CC26 /* s_isinff.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F528CA2C29E1C300E6CC26 /* s_isinff.c */; };
 		F3F7D8ED2933074E00816151 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AA2933074900816151 /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F3F7D8F12933074E00816151 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AB2933074900816151 /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F3F7D8F52933074E00816151 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AC2933074900816151 /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -994,6 +999,11 @@
 		F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_properties.c; sourceTree = "<group>"; };
 		F3E5A6EC2AD5E10800293D83 /* SDL_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_properties.h; path = SDL3/SDL_properties.h; sourceTree = "<group>"; };
 		F3F07D59269640160074468B /* SDL_hidapi_luna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_luna.c; sourceTree = "<group>"; };
+		F3F528C62C29E1C300E6CC26 /* s_isnanf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s_isnanf.c; sourceTree = "<group>"; };
+		F3F528C72C29E1C300E6CC26 /* s_isinf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s_isinf.c; sourceTree = "<group>"; };
+		F3F528C82C29E1C300E6CC26 /* s_isnan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s_isnan.c; sourceTree = "<group>"; };
+		F3F528C92C29E1C300E6CC26 /* s_modf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s_modf.c; sourceTree = "<group>"; };
+		F3F528CA2C29E1C300E6CC26 /* s_isinff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = s_isinff.c; sourceTree = "<group>"; };
 		F3F7D8AA2933074900816151 /* SDL_audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_audio.h; path = SDL3/SDL_audio.h; sourceTree = "<group>"; };
 		F3F7D8AB2933074900816151 /* SDL_platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_platform.h; path = SDL3/SDL_platform.h; sourceTree = "<group>"; };
 		F3F7D8AC2933074900816151 /* SDL_stdinc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_stdinc.h; path = SDL3/SDL_stdinc.h; sourceTree = "<group>"; };
@@ -2161,6 +2171,11 @@
 				A7D8A91323E2514000DCD162 /* s_cos.c */,
 				A7D8A91523E2514000DCD162 /* s_fabs.c */,
 				A7D8A92523E2514000DCD162 /* s_floor.c */,
+				F3F528C72C29E1C300E6CC26 /* s_isinf.c */,
+				F3F528CA2C29E1C300E6CC26 /* s_isinff.c */,
+				F3F528C82C29E1C300E6CC26 /* s_isnan.c */,
+				F3F528C62C29E1C300E6CC26 /* s_isnanf.c */,
+				F3F528C92C29E1C300E6CC26 /* s_modf.c */,
 				A7D8A91A23E2514000DCD162 /* s_scalbn.c */,
 				A7D8A91223E2514000DCD162 /* s_sin.c */,
 				A7D8A91E23E2514000DCD162 /* s_tan.c */,
@@ -2708,7 +2723,9 @@
 				F31A92D228D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */,
 				A1626A3E2617006A003F1973 /* SDL_triangle.c in Sources */,
 				A7D8B3F223E2514300DCD162 /* SDL_thread.c in Sources */,
+				F3F528CF2C29E1C300E6CC26 /* s_isinff.c in Sources */,
 				A7D8B55D23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */,
+				F3F528CB2C29E1C300E6CC26 /* s_isnanf.c in Sources */,
 				A7D8A95723E2514000DCD162 /* SDL_atomic.c in Sources */,
 				A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */,
 				A7D8BB2723E2514500DCD162 /* SDL_displayevents.c in Sources */,
@@ -2756,6 +2773,7 @@
 				A7D8BB7B23E2514500DCD162 /* SDL_dropevents.c in Sources */,
 				A7D8BACD23E2514500DCD162 /* e_atan2.c in Sources */,
 				A7D8BA8B23E2514400DCD162 /* s_sin.c in Sources */,
+				F3F528CE2C29E1C300E6CC26 /* s_modf.c in Sources */,
 				A7D8BBEB23E2574800DCD162 /* SDL_uikitwindow.m in Sources */,
 				F395BF6525633B2400942BFF /* SDL_crc32.c in Sources */,
 				A7D8B5E723E2514300DCD162 /* SDL_power.c in Sources */,
@@ -2788,6 +2806,7 @@
 				A7D8B95023E2514400DCD162 /* SDL_iconv.c in Sources */,
 				F3E5A6EB2AD5E0E600293D83 /* SDL_properties.c in Sources */,
 				A7D8BA9D23E2514400DCD162 /* s_fabs.c in Sources */,
+				F3F528CC2C29E1C300E6CC26 /* s_isinf.c in Sources */,
 				F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */,
 				A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */,
 				F3990DF52A787C10000D8759 /* SDL_sysurl.m in Sources */,
@@ -2855,6 +2874,7 @@
 				A7D8AEA623E2514100DCD162 /* SDL_cocoawindow.m in Sources */,
 				A7D8B43A23E2514300DCD162 /* SDL_sysmutex.c in Sources */,
 				A7D8AAB023E2514100DCD162 /* SDL_syshaptic.c in Sources */,
+				F3F528CD2C29E1C300E6CC26 /* s_isnan.c in Sources */,
 				F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */,
 				A7D8BBD523E2574800DCD162 /* SDL_uikitclipboard.m in Sources */,
 				A7D8B5C923E2514300DCD162 /* SDL_iostreambundlesupport.m in Sources */,
diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index 418a46cee9454..4544980d0e802 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -2066,6 +2066,62 @@ extern SDL_DECLSPEC double SDLCALL SDL_fmod(double x, double y);
  */
 extern SDL_DECLSPEC float SDLCALL SDL_fmodf(float x, float y);
 
+/**
+ * Return whether the value is infinity.
+ *
+ * \param x double-precision floating point value.
+ * \returns non-zero if the value is infinity, 0 otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_isinff
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_isinf(double x);
+
+/**
+ * Return whether the value is infinity.
+ *
+ * \param x floating point value.
+ * \returns non-zero if the value is infinity, 0 otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_isinf
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_isinff(float x);
+
+/**
+ * Return whether the value is NaN.
+ *
+ * \param x double-precision floating point value.
+ * \returns non-zero if the value is NaN, 0 otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_isnanf
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_isnan(double x);
+
+/**
+ * Return whether the value is NaN.
+ *
+ * \param x floating point value.
+ * \returns non-zero if the value is NaN, 0 otherwise.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_isnan
+ */
+extern SDL_DECLSPEC int SDLCALL SDL_isnanf(float x);
+
 /**
  * Compute the natural logarithm of `x`.
  *
diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake
index e12b96b36df6c..69efb8fcadb70 100644
--- a/include/build_config/SDL_build_config.h.cmake
+++ b/include/build_config/SDL_build_config.h.cmake
@@ -152,6 +152,10 @@
 #cmakedefine HAVE_FLOORF 1
 #cmakedefine HAVE_FMOD 1
 #cmakedefine HAVE_FMODF 1
+#cmakedefine HAVE_ISINF 1
+#cmakedefine HAVE_ISINFF 1
+#cmakedefine HAVE_ISNAN 1
+#cmakedefine HAVE_ISNANF 1
 #cmakedefine HAVE_LOG 1
 #cmakedefine HAVE_LOGF 1
 #cmakedefine HAVE_LOG10 1
diff --git a/include/build_config/SDL_build_config_android.h b/include/build_config/SDL_build_config_android.h
index 314e9416c0df4..013bd060eebf5 100644
--- a/include/build_config/SDL_build_config_android.h
+++ b/include/build_config/SDL_build_config_android.h
@@ -109,6 +109,10 @@
 #define HAVE_FLOORF 1
 #define HAVE_FMOD   1
 #define HAVE_FMODF  1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOGF   1
 #define HAVE_LOG10  1
diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h
index b8349930a9ae0..93bf3abea84c3 100644
--- a/include/build_config/SDL_build_config_ios.h
+++ b/include/build_config/SDL_build_config_ios.h
@@ -101,6 +101,10 @@
 #define HAVE_FLOORF 1
 #define HAVE_FMOD   1
 #define HAVE_FMODF  1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOGF   1
 #define HAVE_LOG10  1
diff --git a/include/build_config/SDL_build_config_macos.h b/include/build_config/SDL_build_config_macos.h
index 597cf8874579a..c5bbc199e96a2 100644
--- a/include/build_config/SDL_build_config_macos.h
+++ b/include/build_config/SDL_build_config_macos.h
@@ -105,6 +105,10 @@
 #define HAVE_FLOORF 1
 #define HAVE_FMOD   1
 #define HAVE_FMODF  1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOGF   1
 #define HAVE_LOG10  1
diff --git a/include/build_config/SDL_build_config_windows.h b/include/build_config/SDL_build_config_windows.h
index f147afe0c2b13..457b58e00d420 100644
--- a/include/build_config/SDL_build_config_windows.h
+++ b/include/build_config/SDL_build_config_windows.h
@@ -175,6 +175,10 @@ typedef unsigned int uintptr_t;
 #define HAVE_FABS   1
 #define HAVE_FLOOR  1
 #define HAVE_FMOD   1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOG10  1
 #define HAVE_POW    1
diff --git a/include/build_config/SDL_build_config_wingdk.h b/include/build_config/SDL_build_config_wingdk.h
index 2845b0ecc1479..896499060e43f 100644
--- a/include/build_config/SDL_build_config_wingdk.h
+++ b/include/build_config/SDL_build_config_wingdk.h
@@ -111,6 +111,10 @@
 #define HAVE_FABS   1
 #define HAVE_FLOOR  1
 #define HAVE_FMOD   1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOG10  1
 #define HAVE_POW    1
diff --git a/include/build_config/SDL_build_config_winrt.h b/include/build_config/SDL_build_config_winrt.h
index 1555962b87e8c..7de89bf803b24 100644
--- a/include/build_config/SDL_build_config_winrt.h
+++ b/include/build_config/SDL_build_config_winrt.h
@@ -123,6 +123,10 @@
 #define HAVE_FLOORF 1
 #define HAVE_FMOD   1
 #define HAVE_FMODF  1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOGF   1
 #define HAVE_LOG10  1
diff --git a/include/build_config/SDL_build_config_xbox.h b/include/build_config/SDL_build_config_xbox.h
index 0ca413132f5a8..80c5d95a3dcb1 100644
--- a/include/build_config/SDL_build_config_xbox.h
+++ b/include/build_config/SDL_build_config_xbox.h
@@ -110,6 +110,10 @@
 #define HAVE_FABS   1
 #define HAVE_FLOOR  1
 #define HAVE_FMOD   1
+#define HAVE_ISINF  1
+#define HAVE_ISINF_FLOAT_MACRO 1
+#define HAVE_ISNAN  1
+#define HAVE_ISNAN_FLOAT_MACRO 1
 #define HAVE_LOG    1
 #define HAVE_LOG10  1
 #define HAVE_POW    1
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 070835992ebca..cf0d4ac6a1f9d 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -930,7 +930,11 @@ SDL3_0.0.0 {
     SDL_iscntrl;
     SDL_isdigit;
     SDL_isgraph;
+    SDL_isinf;
+    SDL_isinff;
     SDL_islower;
+    SDL_isnan;
+    SDL_isnanf;
     SDL_isprint;
     SDL_ispunct;
     SDL_isspace;
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 9b3d0aed2e383..3d0eaf0b7299e 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -955,7 +955,11 @@
 #define SDL_iscntrl SDL_iscntrl_REAL
 #define SDL_isdigit SDL_isdigit_REAL
 #define SDL_isgraph SDL_isgraph_REAL
+#define SDL_isinf SDL_isinf_REAL
+#define SDL_isinff SDL_isinff_REAL
 #define SDL_islower SDL_islower_REAL
+#define SDL_isnan SDL_isnan_REAL
+#define SDL_isnanf SDL_isnanf_REAL
 #define SDL_isprint SDL_isprint_REAL
 #define SDL_ispunct SDL_ispunct_REAL
 #define SDL_isspace SDL_isspace_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index bc9b6bfe7a307..d2217995faad4 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -964,7 +964,11 @@ SDL_DYNAPI_PROC(int,SDL_isblank,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_iscntrl,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_isdigit,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_isgraph,(int a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_isinf,(double a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_isinff,(float a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_islower,(int a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_isnan,(double a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_isnanf,(float a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_isprint,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_ispunct,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_isspace,(int a),(a),return)
diff --git a/src/libm/math_libm.h b/src/libm/math_libm.h
index 1313a075df326..bbe4ce87a3ddf 100644
--- a/src/libm/math_libm.h
+++ b/src/libm/math_libm.h
@@ -26,21 +26,25 @@
 
 /* Math routines from uClibc: http://www.uclibc.org */
 
-double SDL_uclibc_atan(double x);
-double SDL_uclibc_atan2(double y, double x);
-double SDL_uclibc_copysign(double x, double y);
-double SDL_uclibc_cos(double x);
-double SDL_uclibc_exp(double x);
-double SDL_uclibc_fabs(double x);
-double SDL_uclibc_floor(double x);
-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_pow(double x, double y);
-double SDL_uclibc_scalbn(double x, int n);
-double SDL_uclibc_sin(double x);
-double SDL_uclibc_sqrt(double x);
-double SDL_uclibc_tan(double x);
+extern double SDL_uclibc_atan(double x);
+extern double SDL_uclibc_atan2(double y, double x);
+extern double SDL_uclibc_copysign(double x, double y);
+extern double SDL_uclibc_cos(double x);
+extern double SDL_uclibc_exp(double x);
+extern double SDL_uclibc_fabs(double x);
+extern double SDL_uclibc_floor(double x);
+extern double SDL_uclibc_fmod(double x, double y);
+extern int SDL_uclibc_isinf(double x);
+extern int SDL_uclibc_isinff(float x);
+extern int SDL_uclibc_isnan(double x);
+extern int SDL_uclibc_isnanf(float x);
+extern double SDL_uclibc_log(double x);
+extern double SDL_uclibc_log10(double x);
+extern double SDL_uclibc_modf(double x, double *y);
+extern double SDL_uclibc_pow(double x, double y);
+extern double SDL_uclibc_scalbn(double x, int n);
+extern double SDL_uclibc_sin(double x);
+extern double SDL_uclibc_sqrt(double x);
+extern double SDL_uclibc_tan(double x);
 
 #endif /* math_libm_h_ */
diff --git a/src/libm/math_private.h b/src/libm/math_private.h
index 9beb41027ef13..b7d60e4310719 100644
--- a/src/libm/math_private.h
+++ b/src/libm/math_private.h
@@ -25,6 +25,7 @@
 #define libm_hidden_proto(x)
 #define libm_hidden_def(x)
 #define strong_alias(x, y)
+#define weak_alias(x, y)
 
 #if !defined(SDL_PLATFORM_HAIKU) && !defined(SDL_PLATFORM_PSP) && !defined(SDL_PLATFORM_3DS) && !defined(SDL_PLATFORM_PS2) /* already defined in a system header. */
 typedef unsigned int u_int32_t;
@@ -38,6 +39,14 @@ typedef unsigned int u_int32_t;
 #define fabs            SDL_uclibc_fabs
 #define floor           SDL_uclibc_floor
 #define __ieee754_fmod  SDL_uclibc_fmod
+#undef __isinf
+#define __isinf         SDL_uclibc_isinf
+#undef __isinff
+#define __isinff        SDL_uclibc_isinff
+#undef __isnan
+#define __isnan         SDL_uclibc_isnan
+#undef __isnanf
+#define __isnanf        SDL_uclibc_isnanf
 #define __ieee754_log   SDL_uclibc_log
 #define __ieee754_log10 SDL_uclibc_log10
 #define modf            SDL_uclibc_modf
@@ -181,48 +190,45 @@ do {								\
 } while (0)
 
 /* ieee style elementary functions */
-extern double
-__ieee754_sqrt(double)
-    attribute_hidden;
-     extern double __ieee754_acos(double) attribute_hidden;
-     extern double __ieee754_acosh(double) attribute_hidden;
-     extern double __ieee754_log(double) attribute_hidden;
-     extern double __ieee754_atanh(double) attribute_hidden;
-     extern double __ieee754_asin(double) attribute_hidden;
-     extern double __ieee754_atan2(double, double) attribute_hidden;
-     extern double __ieee754_exp(double) attribute_hidden;
-     extern double __ieee754_cosh(double) attribute_hidden;
-     extern double __ieee754_fmod(double, double) attribute_hidden;
-     extern double __ieee754_pow(double, double) attribute_hidden;
-     extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
-     extern double __ieee754_gamma_r(double, int *) attribute_hidden;
-     extern double __ieee754_lgamma(double) attribute_hidden;
-     extern double __ieee754_gamma(double) attribute_hidden;
-     extern double __ieee754_log10(double) attribute_hidden;
-     extern double __ieee754_sinh(double) attribute_hidden;
-     extern double __ieee754_hypot(double, double) attribute_hidden;
-     extern double __ieee754_j0(double) attribute_hidden;
-     extern double __ieee754_j1(double) attribute_hidden;
-     extern double __ieee754_y0(double) attribute_hidden;
-     extern double __ieee754_y1(double) attribute_hidden;
-     extern double __ieee754_jn(int, double) attribute_hidden;
-     extern double __ieee754_yn(int, double) attribute_hidden;
-     extern double __ieee754_remainder(double, double) attribute_hidden;
-     extern int32_t __ieee754_rem_pio2(double, double *) attribute_hidden;
+extern double __ieee754_sqrt(double) attribute_hidden;
+extern double __ieee754_acos(double) attribute_hidden;
+extern double __ieee754_acosh(double) attribute_hidden;
+extern double __ieee754_log(double) attribute_hidden;
+extern double __ieee754_atanh(double) attribute_hidden;
+extern double __ieee754_asin(double) attribute_hidden;
+extern double __ieee754_atan2(double, double) attribute_hidden;
+extern double __ieee754_exp(double) attribute_hidden;
+extern double __ieee754_cosh(double) attribute_hidden;
+extern double __ieee754_fmod(double, double) attribute_hidden;
+extern double __ieee754_pow(double, double) attribute_hidden;
+extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
+extern double __ieee754_gamma_r(double, int *) attribute_hidden;
+extern double __ieee754_lgamma(double) attribute_hidden;
+extern double __ieee754_gamma(double) attribute_hidden;
+extern double __ieee754_log10(double) attribute_hidden;
+extern double __ieee754_sinh(double) attribute_hidden;
+extern double __ieee754_hypot(double, double) attribute_hidden;
+extern double __ieee754_j0(double) attribute_hidden;
+extern double __ieee754_j1(double) attribute_hidden;
+extern double __ieee754_y0(double) attribute_hidden;
+extern double __ieee754_y1(double) attribute_hidden;
+extern double __ieee754_jn(int, double) attribute_hidden;
+extern double __ieee754_yn(int, double) attribute_hidden;
+extern double __ieee754_remainder(double, double) attribute_hidden;
+extern int32_t __ieee754_rem_pio2(double, double *) attribute_hidden;
 #if defined(_SCALB_INT)
-     extern double __ieee754_scalb(double, int) attribute_hidden;
+extern double __ieee754_scalb(double, int) attribute_hidden;
 #else
-     extern double __ieee754_scalb(double, double) attribute_hidden;
+extern double __ieee754_scalb(double, double) attribute_hidden;
 #endif
 
 /* fdlibm kernel function */
 #ifndef _IEEE_LIBM
-     extern double __kernel_standard(double, double, int) attribute_hidden;
+extern double __kernel_standard(double, double, int) attribute_hidden;
 #endif
-     extern double __kernel_sin(double, double, int) attribute_hidden;
-     extern double __kernel_cos(double, double) attribute_hidden;
-     extern double __kernel_tan(double, double, int) attribute_hidden;
-     extern int32_t __kernel_rem_pio2(const double *, double *, int, int, const unsigned int,
-                                  const int32_t *) attribute_hidden;
+extern double __kernel_sin(double, double, int) attribute_hidden;
+extern double __kernel_cos(double, double) attribute_hidden;
+extern double __kernel_tan(double, double, int) attribute_hidden;
+extern int32_t __kernel_rem_pio2(const double *, double *, int, int, const unsigned int, const int32_t *) attribute_hidden;
 
 #endif /* _MATH_PRIVATE_H_ */
diff --git a/src/libm/s_isinf.c b/src/libm/s_isinf.c
new file mode 100644
index 0000000000000..9486b05903f25
--- /dev/null
+++ b/src/libm/s_isinf.c
@@ -0,0 +1,24 @@
+#include "SDL_internal.h"
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changed to return -1 for -Inf by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+/*
+ * isinf(x) returns 1 is x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int __isinf(double x)
+{
+	int32_t hx,lx;
+	EXTRACT_WORDS(hx,lx,x);
+	lx |= (hx & 0x7fffffff) ^ 0x7ff00000;
+	lx |= -lx;
+	return ~(lx >> 31) & (hx >> 30);
+}
+libm_hidden_def(__isinf)
diff --git a/src/libm/s_isinff.c b/src/libm/s_isinff.c
new file mode 100644
index 0000000000000..184c9aa6caf4a
--- /dev/null
+++ b/src/libm/s_isinff.c
@@ -0,0 +1,24 @@
+#include "SDL_internal.h"
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+/*
+ * isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int __isinff (float x)
+{
+	int32_t ix,t;
+	GET_FLOAT_WORD(ix,x);
+	t = ix & 0x7fffffff;
+	t ^= 0x7f800000;
+	t |= -t;
+	return ~(t >> 31) & (ix >> 30);
+}
+libm_hidden_def(__isinff)
diff --git a/src/libm/s_isnan.c b/src/libm/s_isnan.c
new file mode 100644
index 0000000000000..4831086adcc45
--- /dev/null
+++ b/src/libm/s_isnan.c
@@ -0,0 +1,31 @@
+#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.
+ * ====================================================
+ */
+
+/*
+ * isnan(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int __isnan(double x)
+{
+	int32_t hx,lx;
+	EXTRACT_WORDS(hx,lx,x);
+	hx &= 0x7fffffff;
+	hx |= (u_int32_t)(lx|(-lx))>>31;
+	hx = 0x7ff00000 - hx;
+	return (int)(((u_int32_t)hx)>>31);
+}
+weak_alias(__isnan, isnan)
+libm_hidden_def(__isnan)
diff --git a/src/libm/s_isnanf.c b/src/libm/s_isnanf.c
new file mode 100644
index 0000000000000..1cb308cfa98ca
--- /dev/null
+++ b/src/libm/s_isnanf.c
@@ -0,0 +1,33 @@
+#include "SDL_internal.h"
+/* s_isnanf.c -- float version of s_isnan.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.
+ * ====================================================
+ */
+
+/*
+ * isnanf(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int __isnanf(float x)
+{
+	int32_t ix;
+	GET_FLOAT_WORD(ix,x);
+	ix &= 0x7fffffff;
+	ix = 0x7f800000 - ix;
+	return (int)(((u_int32_t)(ix))>>31);
+}
+libm_hidden_def(__isnanf)
diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c
index d655d9dc4ef7d..3a8443735d510 100644
--- a/src/stdlib/SDL_stdlib.c
+++ b/src/stdlib/SDL_stdlib.c
@@ -272,6 +272,46 @@ float SDL_fmodf(float x, float y)
 #endif
 }
 
+SDL_bool SDL_isinf(double x)
+{
+#ifdef HAVE_ISINF
+    return isinf(x);
+#else
+    return SDL_uclibc_isinf(x);
+#endif
+}
+
+SDL_bool SDL_isinff(float x)
+{
+#ifdef HAVE_ISINF_FLOAT_MACRO
+    return isinf(x);
+#elif defined(HAVE_ISINFF)
+    return isinff(x);
+#else
+    return SDL_uclibc_isinff(x);
+#endif
+}
+
+SDL_bool SDL_isnan(double x)
+{
+#ifdef HAVE_ISNAN
+    return isnan(x);
+#else
+    return SDL_uclibc_isnan(x);
+#endif
+}
+
+SDL_bool SDL_isnanf(float x)
+{
+#ifdef HAVE_ISNAN_FLOAT_MACRO
+    return isnan(x);
+#elif defined(HAVE_ISNANF)
+    return isnanf(x);
+#else
+    return SDL_uclibc_isnanf(x);
+#endif
+}
+
 double SDL_log(double x)
 {
 #ifdef HAVE_LOG

(Patch may be truncated, please check the link at the top of this post.)