@@ -209,7 +209,46 @@ version(mir_bignum_test)
209209 else
210210 {
211211 str.fromString! float .should == str._stdc_parse! float ;
212- str.fromString! double .should == str._stdc_parse! double ;
212+ auto mirStrValue = str.fromString! double ;
213+ auto crtStrValue = str._stdc_parse! double ;
214+
215+ version (CRuntime_Microsoft ) {
216+ // Some Windows CRTs clamp extreme underflow to min-subnormal instead of 0.
217+ // Accept both behaviors *only* at the very bottom of the subnormal range.
218+ bool equalOrTinyUnderflow (double a, double b)
219+ {
220+ import core.stdc.math : fpclassify, FP_SUBNORMAL ;
221+ import mir.math.common: fabs;
222+ import mir.math.ieee: signbit;
223+ import std.math.operations : nextafter;
224+
225+ if (a == b) return true ;
226+ if (signbit(a) != signbit(b)) return false ;
227+
228+ enum double minSub = nextafter(0.0 , 1.0 ); // smallest positive subnormal
229+
230+ const aa = fabs(a);
231+ const bb = fabs(b);
232+
233+ // 0 <-> min-subnormal (or similar one-ULP-at-zero behavior)
234+ if (aa == 0.0 && bb > 0.0 )
235+ return fpclassify (b) == FP_SUBNORMAL && bb <= minSub;
236+ if (bb == 0.0 && aa > 0.0 )
237+ return fpclassify (a) == FP_SUBNORMAL && aa <= minSub;
238+
239+ // If both are subnormal, permit differences only if both are at the very bottom.
240+ if (fpclassify(a) == FP_SUBNORMAL && fpclassify(b) == FP_SUBNORMAL )
241+ return aa <= minSub && bb <= minSub;
242+
243+ return false ;
244+ }
245+ if (! equalOrTinyUnderflow(mirStrValue, crtStrValue)) {
246+ mirStrValue.should == crtStrValue;
247+ }
248+ } else {
249+ mirStrValue.should == crtStrValue;
250+ }
251+
213252 version (Windows ) // No precise real parsing on windows
214253 {
215254 }
0 commit comments