[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