From: Jan Dubois Date: Wed, 22 Mar 2006 22:49:11 +0000 (-0800) Subject: RE: [PATCH, no, really!] Re: [perl #38779] NAN's on Win32 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cab190d4d715e2c6ec26ee0ebfd0bc6fb0f03bd3;p=p5sagit%2Fp5-mst-13.2.git RE: [PATCH, no, really!] Re: [perl #38779] NAN's on Win32 From: "Jan Dubois" Message-ID: <060201c64e45$e4ca7020$2217a8c0@candy> Also, back out change #27567. p4raw-link: @27567 on //depot/perl: 9bf76a6a2fc16ab628a46452e34352d3e3d71674 p4raw-id: //depot/perl@27576 --- diff --git a/README.win32 b/README.win32 index 4815a32..066a6dc 100644 --- a/README.win32 +++ b/README.win32 @@ -859,12 +859,6 @@ Thus, signals may work only for simple things like setting a flag variable in the handler. Using signals under this port should currently be considered unsupported. -Numeric comparisons involving "Not a Number" (NaN, an IEEE floating point -feature) will give incorrect results if you build with Visual C++ Version 6 -or earlier -- see I in -L -for details. If possible, you should build using a later version of VC++. - Please send detailed descriptions of any problems and solutions that you may find to EFE, along with the output produced by C. @@ -915,6 +909,6 @@ Win9x support was added in 5.6 (Benjamin Stuhl). Support for 64-bit Windows added in 5.8 (ActiveState Corp). -Last updated: 22 March 2006 +Last updated: 30 September 2005 =cut diff --git a/pp.c b/pp.c index 6b3ead8..99f0b06 100644 --- a/pp.c +++ b/pp.c @@ -1714,8 +1714,15 @@ PP(pp_lt) } #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; } } @@ -1790,8 +1797,15 @@ PP(pp_gt) } #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; } } @@ -1866,8 +1880,15 @@ PP(pp_le) } #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; } } @@ -1942,8 +1963,15 @@ PP(pp_ge) } #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; } } @@ -2011,8 +2039,15 @@ PP(pp_ne) } #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; } } diff --git a/pp_hot.c b/pp_hot.c index c34fb90..3b4d8ed 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -363,8 +363,15 @@ PP(pp_eq) } #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; } } diff --git a/sv.c b/sv.c index cb8d217..d8b4d74 100644 --- a/sv.c +++ b/sv.c @@ -1895,6 +1895,13 @@ S_sv_2iuv_common(pTHX_ SV *sv) { certainly cast into the IV range at IV_MAX, whereas the correct answer is the UV IV_MAX +1. Hence < ensures that dodgy boundary 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) diff --git a/win32/win32.h b/win32/win32.h index e56c4df..7be8482 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -210,6 +210,11 @@ typedef unsigned short mode_t; #define isnan _isnan +#if _MSC_VER < 1300 +/* VC6 has broken NaN semantics: NaN == NaN returns true instead of false */ +#define NAN_COMPARE_BROKEN 1 +#endif + #endif /* _MSC_VER */ #ifdef __MINGW32__ /* Minimal Gnu-Win32 */