in reply to Re^4: Q: NaN again
in thread Q: NaN again
F:\>perl -we "$a='nan'; print sprintf('%.2f',$a)" 0.00
--- pp.c.orig Wed Mar 22 19:35:45 2006 +++ pp.c Wed Mar 22 21:43:04 2006 @@ -1732,8 +1732,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left < right)); +#else dPOPnv; SETs(boolSV(TOPn < value)); +#endif RETURN; } } @@ -1808,8 +1815,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left > right)); +#else dPOPnv; SETs(boolSV(TOPn > value)); +#endif RETURN; } } @@ -1884,8 +1898,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left <= right)); +#else dPOPnv; SETs(boolSV(TOPn <= value)); +#endif RETURN; } } @@ -1960,8 +1981,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left >= right)); +#else dPOPnv; SETs(boolSV(TOPn >= value)); +#endif RETURN; } } @@ -2029,8 +2057,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETYES; + SETs(boolSV(left != right)); +#else dPOPnv; SETs(boolSV(TOPn != value)); +#endif RETURN; } } --- pp_hot.c.orig Wed Mar 22 19:35:45 2006 +++ pp_hot.c Wed Mar 22 21:42:38 2006 @@ -306,8 +306,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left == right)); +#else dPOPnv; SETs(boolSV(TOPn == value)); +#endif RETURN; } } --- sv.c.orig Wed Mar 22 21:47:13 2006 +++ sv.c Wed Mar 22 21:31:27 2006 @@ -2134,6 +2134,13 @@ certainly cast into the IV range at IV_MAX, whereas the correc +t answer is the UV IV_MAX +1. Hence < ensures that dodgy boundar +y cases go to UV */ +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + if (Perl_isnan(SvNVX(sv))) { + SvUV_set(sv, 0); + SvIsUV_on(sv); + } + else +#endif if (SvNVX(sv) < (NV)IV_MAX + 0.5) { SvIV_set(sv, I_V(SvNVX(sv))); if (SvNVX(sv) == (NV) SvIVX(sv) --- win32/win32.h.orig Wed Mar 22 19:35:49 2006 +++ win32/win32.h Wed Mar 22 21:35:54 2006 @@ -210,6 +210,11 @@ #define isnan _isnan +#if _MSC_VER < 1300 +/* VC6 has broken NaN semantics: NaN == NaN returns true instead of f +alse */ +#define NAN_COMPARE_BROKEN 1 +#endif + #endif /* _MSC_VER */ #ifdef __MINGW32__ /* Minimal Gnu-Win32 */
|
|---|