From ce1dc3a2b18e119272aea99c670a3a76d5c78b08 Mon Sep 17 00:00:00 2001 From: OmniBlade Date: Thu, 17 Sep 2026 14:20:29 +0100 Subject: [PATCH] fix(msvc): Attempt to force correct precision on 32bit MSVC. --- CMakeLists.txt | 5 +++++ float/e_powf.c | 14 +++++++------- float/s_erff.c | 32 ++++++++++++++++---------------- float/s_scalbnf.c | 12 ++++++------ 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 557c802..afc57b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,11 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU") target_compile_options(gamemath PRIVATE -fno-gnu89-inline -fno-builtin -fno-strict-aliasing -ffp-contract=off -Wno-implicit-function-declaration) elseif(MSVC) target_compile_options(gamemath PRIVATE /wd4146 /wd4244 /wd4554 /wd4723 /wd4756) + if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + # These files must be compiled as strict in msvc to generate correct code. + set_source_files_properties(float/e_powf.c PROPERTIES COMPILE_FLAGS /fp:strict) + set_source_files_properties(float/s_scalbnf.c PROPERTIES COMPILE_FLAGS /fp:strict) + endif() endif() set_target_properties(gamemath PROPERTIES OUTPUT_NAME gm) diff --git a/float/e_powf.c b/float/e_powf.c index c9b4c66..3743d3d 100644 --- a/float/e_powf.c +++ b/float/e_powf.c @@ -100,7 +100,7 @@ __ieee754_powf(float x, float y) return (hy<0)?-y: zero; } if(iy==0x3f800000) { /* y is +-1 */ - if(hy<0) return one/x; else return x; + if(hy<0) return (one/x); else return x; } if(hy==0x40000000) return x*x; /* y is 2 */ if(hy==0x3f000000) { /* y is 0.5 */ @@ -125,7 +125,7 @@ __ieee754_powf(float x, float y) n = ((uint32_t)hx>>31)-1; /* (x<0)**(non-int) is NaN */ - if((n|yisint)==0) return (x-x)/(x-x); + if((n|yisint)==0) return ((x-x)/(x-x)); sn = one; /* s (sign of result -ve**odd) = -1 else = 1 */ if((n|(yisint-1))==0) sn = -one;/* (-ve)**(odd int) */ @@ -207,14 +207,14 @@ __ieee754_powf(float x, float y) z = p_l+p_h; GET_FLOAT_WORD(j,z); if (j>0x43000000) /* if z > 128 */ - return sn*huge*huge; /* overflow */ + return (sn*huge*huge); /* overflow */ else if (j==0x43000000) { /* if z == 128 */ - if(p_l+ovt>z-p_h) return sn*huge*huge; /* overflow */ + if(p_l+ovt>z-p_h) return (sn*huge*huge); /* overflow */ } else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */ - return sn*tiny*tiny; /* underflow */ + return (sn*tiny*tiny); /* underflow */ else if (j==0xc3160000){ /* z == -150 */ - if(p_l<=z-p_h) return sn*tiny*tiny; /* underflow */ + if(p_l<=z-p_h) return (sn*tiny*tiny); /* underflow */ } /* * compute 2**(p_h+p_l) @@ -245,5 +245,5 @@ __ieee754_powf(float x, float y) j += (n<<23); if((j>>23)<=0) z = gm_scalbnf(z,n); /* subnormal output */ else SET_FLOAT_WORD(z,j); - return sn*z; + return (sn*z); } diff --git a/float/s_erff.c b/float/s_erff.c index 8fd0ab7..e4a7f7e 100644 --- a/float/s_erff.c +++ b/float/s_erff.c @@ -89,23 +89,23 @@ gm_erff(float x) if(ix < 0x3f580000) { /* |x|<0.84375 */ if(ix < 0x38800000) { /* |x|<2**-14 */ if (ix < 0x04000000) /* |x|<0x1p-119 */ - return (8*x+efx8*x)/8; /* avoid spurious underflow */ - return x + efx*x; + return ((8*x+efx8*x)/8); /* avoid spurious underflow */ + return (x + efx*x); } z = x*x; r = pp0+z*(pp1+z*pp2); s = one+z*(qq1+z*(qq2+z*qq3)); y = r/s; - return x + x*y; + return (x + x*y); } if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ - s = gm_fabsf(x)-one; + s = (float)(gm_fabsf(x))-one; P = pa0+s*(pa1+s*(pa2+s*pa3)); Q = one+s*(qa1+s*(qa2+s*qa3)); - if(hx>=0) return erx + P/Q; else return -erx - P/Q; + if(hx>=0) return (erx + P/Q); else return (-erx - P/Q); } if (ix >= 0x40800000) { /* inf>|x|>=4 */ - if(hx>=0) return one-tiny; else return tiny-one; + if(hx>=0) return (one-tiny); else return (tiny-one); } x = gm_fabsf(x); s = one/(x*x); @@ -117,8 +117,8 @@ gm_erff(float x) S=one+s*(sb1+s*(sb2+s*sb3)); } SET_FLOAT_WORD(z,hx&0xffffe000); - r = gm_expf(-z*z-0.5625F)*gm_expf((z-x)*(z+x)+R/S); - if(hx>=0) return one-r/x; else return r/x-one; + r = (float)(gm_expf(-z*z-0.5625F))*(float)(gm_expf((z-x)*(z+x)+R/S)); + if(hx>=0) return (one-r/x); else return (r/x-one); } float @@ -135,21 +135,21 @@ gm_erfcf(float x) if(ix < 0x3f580000) { /* |x|<0.84375 */ if(ix < 0x33800000) /* |x|<2**-24 */ - return one-x; + return (one-x); z = x*x; r = pp0+z*(pp1+z*pp2); s = one+z*(qq1+z*(qq2+z*qq3)); y = r/s; if(hx < 0x3e800000) { /* x<1/4 */ - return one-(x+x*y); + return (one-(x+x*y)); } else { r = x*y; r += (x-half); - return half - r ; + return (half - r) ; } } if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ - s = gm_fabsf(x)-one; + s = (float)(gm_fabsf(x))-one; P = pa0+s*(pa1+s*(pa2+s*pa3)); Q = one+s*(qa1+s*(qa2+s*qa3)); if(hx>=0) { @@ -165,14 +165,14 @@ gm_erfcf(float x) R=ra0+s*(ra1+s*(ra2+s*ra3)); S=one+s*(sa1+s*(sa2+s*sa3)); } else { /* |x| >= 2.85715 ~ 1/.35 */ - if(hx<0&&ix>=0x40a00000) return two-tiny;/* x < -5 */ + if(hx<0&&ix>=0x40a00000) return (two-tiny);/* x < -5 */ R=rb0+s*(rb1+s*rb2); S=one+s*(sb1+s*(sb2+s*sb3)); } SET_FLOAT_WORD(z,hx&0xffffe000); - r = gm_expf(-z*z-0.5625F)*gm_expf((z-x)*(z+x)+R/S); - if(hx>0) return r/x; else return two-r/x; + r = (float)(gm_expf(-z*z-0.5625F))*(float)(gm_expf((z-x)*(z+x)+R/S)); + if(hx>0) return (r/x); else return (two-r/x); } else { - if(hx>0) return tiny*tiny; else return two-tiny; + if(hx>0) return (tiny*tiny); else return (two-tiny); } } diff --git a/float/s_scalbnf.c b/float/s_scalbnf.c index 59be7a0..84030d8 100644 --- a/float/s_scalbnf.c +++ b/float/s_scalbnf.c @@ -33,21 +33,21 @@ gm_scalbnf (float x, int n) x *= two25; GET_FLOAT_WORD(ix,x); k = ((ix&0x7f800000)>>23) - 25; - if (n< -50000) return tiny*x; /*underflow*/ + if (n< -50000) return (tiny*x); /*underflow*/ } - if (k==0xff) return x+x; /* NaN or Inf */ + if (k==0xff) return (x+x); /* NaN or Inf */ k = k+n; - if (k > 0xfe) return huge*gm_copysignf(huge,x); /* overflow */ + if (k > 0xfe) return (huge*(float)(gm_copysignf(huge,x))); /* overflow */ if (k > 0) /* normal result */ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} if (k <= -25) { if (n > 50000) /* in case integer overflow in n+k */ - return huge*gm_copysignf(huge,x); /*overflow*/ - else return tiny*gm_copysignf(tiny,x); /*underflow*/ + return (huge*(float)(gm_copysignf(huge,x))); /*overflow*/ + else return (tiny*(float)(gm_copysignf(tiny,x))); /*underflow*/ } k += 25; /* subnormal result */ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); - return x*twom25; + return (x*twom25); } #if (defined(__clang__) || defined(__GNUC__)) && !defined(__APPLE__)