summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.win328
-rw-r--r--pp.c35
-rw-r--r--pp_hot.c7
-rw-r--r--sv.c7
-rw-r--r--win32/win32.h5
5 files changed, 55 insertions, 7 deletions
diff --git a/README.win32 b/README.win32
index 4815a32add..066a6dc752 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<Floating-Point Comparison> in
-L<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep05282002.asp>
-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 E<lt>F<perlbug@perl.org>E<gt>, along with the output
produced by C<perl -V>.
@@ -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 6b3ead8ec0..99f0b06feb 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 c34fb90fb2..3b4d8ed076 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 cb8d21742e..d8b4d740f5 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 e56c4df13d..7be8482ce4 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 */