[MLton-commit] r7505

Matthew Fluet fluet at mlton.org
Fri Feb 18 13:18:58 PST 2011


RealX.equals should return true for two nan values.

As noted previously, constant propagation and common subexpression
elimination won't combine nan values, because the underlying
Real{32,64}.== returns false for any comparison with nan values.

But RealX.t denotes a floating-point constant, for which it makes
sense to take one nan value as equal to another nan value.

Ideally, RealX.equals would use bit-wise equality since there are
multiple representations for nan.  However, SML/NJ doesn't support the
PackReal structures that would be required to compare real values as
bit patterns.
----------------------------------------------------------------------

U   mlton/trunk/lib/mlton/basic/real.sig
U   mlton/trunk/mlton/atoms/real-x.fun

----------------------------------------------------------------------

Modified: mlton/trunk/lib/mlton/basic/real.sig
===================================================================
--- mlton/trunk/lib/mlton/basic/real.sig	2011-02-18 21:18:54 UTC (rev 7504)
+++ mlton/trunk/lib/mlton/basic/real.sig	2011-02-18 21:18:57 UTC (rev 7505)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
  * Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
  *    Jagannathan, and Stephen Weeks.
  *
@@ -60,6 +60,7 @@
       val input: In0.t -> t
       val inverse: t -> t
       val isFinite: t -> bool
+      val isNan: t -> bool
       val layout: t -> Layout.t
       val ln: t -> t
       val log2: t -> t

Modified: mlton/trunk/mlton/atoms/real-x.fun
===================================================================
--- mlton/trunk/mlton/atoms/real-x.fun	2011-02-18 21:18:54 UTC (rev 7504)
+++ mlton/trunk/mlton/atoms/real-x.fun	2011-02-18 21:18:57 UTC (rev 7505)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
  * Copyright (C) 2004-2006 Henry Cejtin, Matthew Fluet, Suresh
  *    Jagannathan, and Stephen Weeks.
  *
@@ -42,9 +42,12 @@
        | R64 => doit (Real64.fromString, Real64.isFinite, Real64)
    end
 
-(* We need to check the sign bit when comparing reals so that we don't treat
- * 0.0 and ~0.0 identically.  The difference between the two is detectable by
- * user programs that look at the sign bit.
+(* RealX.equals determines if two floating-point constants are equal.
+ * Must check the sign bit, since Real{32,64}.== ignores the sign of
+ * zeros; the difference between 0.0 and ~0.0 is observable by
+ * programs that examine the sign bit.
+ * Must check for nan, since Real{32,64}.== returns false for any
+ * comparison with nan values.
  *)
 fun equals (r, r') =
    case (r, r') of
@@ -52,13 +55,15 @@
          let
             open Real32
          in
-            equals (r, r') andalso signBit r = signBit r'
+            (equals (r, r') andalso signBit r = signBit r')
+            orelse (isNan r andalso isNan r')
          end
     | (Real64 r, Real64 r') =>
          let
             open Real64
          in
-            equals (r, r') andalso signBit r = signBit r'
+            (equals (r, r') andalso signBit r = signBit r')
+            orelse (isNan r andalso isNan r')
          end
     | _ => false
 




More information about the MLton-commit mailing list