caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Weird behavior with nan's and min/max
@ 2003-10-14 14:37 Yaron Minsky
  2003-10-14 14:56 ` Yaron Minsky
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Yaron Minsky @ 2003-10-14 14:37 UTC (permalink / raw)
  To: caml-list

min and max have pretty strange behavior when it comes to nan's.  Here's
an example:

# min 3. nan;;
- : float = 3.
# min  nan 3.;;
- : float = nan

When you think about it, the reason for this is clear.  comparisons
involving nan's always return false, so if you simply implement min as
follows:

   if x < y then x else y

the the result will depend on the order.

Now here's the weird bit.  I decided I wanted a polymorphic comparison
that wouldn't have this problem.  But this is a little harder than it
seems, since it turns out that specialized float version of equality is
different from the polymorphic version.  Here's the example:

# let raw_min = min
val raw_min : 'a -> 'a -> 'a = <fun>
# let min x y =
  if not (y = y) then y
  else if not (x = x) then x
  else raw_min x y
;;
        val min : 'a -> 'a -> 'a = <fun>
# let fmin (x:float) y =
  if not (y = y) then y
  else if not (x = x) then x
  else raw_min x y
;;
        val fmin : float -> float -> float = <fun>
# fmin 3. nan;;
- : float = nan
# fmin nan 3.;;
- : float = nan
# min nan 3.;;
- : float = nan
# min 3. nan;;
- : float = 3.

So, does this count as a bug?  Any ideas about how to fix this behavior in
a reasonably efficient way?

Yaron

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-14 14:37 [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
@ 2003-10-14 14:56 ` Yaron Minsky
  2003-10-14 20:52   ` Yaron Minsky
  2003-10-16 13:16 ` Xavier Leroy
  2003-10-16 23:55 ` [Caml-list] " Jed Davis
  2 siblings, 1 reply; 18+ messages in thread
From: Yaron Minsky @ 2003-10-14 14:56 UTC (permalink / raw)
  To: caml-list

Here's a working solution, I think.

let raw_min = min
let raw_max = max

let nan_or_equal x y =
  not (x < y) && not (x > y)

(** min and max that choose nan if its there *)
let min x y =
  if x = y then x
  else if nan_or_equal x y then nan
  else raw_min x y

let max x y =
  if x = y then x
  else if nan_or_equal x y then nan
  else raw_max x y


> min and max have pretty strange behavior when it comes to nan's.  Here's
> an example:
>
> # min 3. nan;;
> - : float = 3.
> # min  nan 3.;;
> - : float = nan
>
> When you think about it, the reason for this is clear.  comparisons
> involving nan's always return false, so if you simply implement min as
> follows:
>
>    if x < y then x else y
>
> the the result will depend on the order.
>
> Now here's the weird bit.  I decided I wanted a polymorphic comparison
> that wouldn't have this problem.  But this is a little harder than it
> seems, since it turns out that specialized float version of equality is
> different from the polymorphic version.  Here's the example:
>
> # let raw_min = min
> val raw_min : 'a -> 'a -> 'a = <fun>
> # let min x y =
>   if not (y = y) then y
>   else if not (x = x) then x
>   else raw_min x y
> ;;
>         val min : 'a -> 'a -> 'a = <fun>
> # let fmin (x:float) y =
>   if not (y = y) then y
>   else if not (x = x) then x
>   else raw_min x y
> ;;
>         val fmin : float -> float -> float = <fun>
> # fmin 3. nan;;
> - : float = nan
> # fmin nan 3.;;
> - : float = nan
> # min nan 3.;;
> - : float = nan
> # min 3. nan;;
> - : float = 3.
>
> So, does this count as a bug?  Any ideas about how to fix this behavior in
> a reasonably efficient way?
>
> Yaron
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-14 14:56 ` Yaron Minsky
@ 2003-10-14 20:52   ` Yaron Minsky
  2003-10-14 23:43     ` skaller
  0 siblings, 1 reply; 18+ messages in thread
From: Yaron Minsky @ 2003-10-14 20:52 UTC (permalink / raw)
  To: caml-list

I've gotten a bunch of replies on this, some pointing out that the proper
result could be achieved with various methods for detecting nan's
explicitly.  This kind of misses my point, which is that this leads to
some pretty serious violations of the principle of least surprise.

The first is that adding a type annotation to a function can change its
semantics:  the specialized min function I came up with works
substantively differently depending on whether it's known at compile-time
that it operates only on floats.

The second weirdness is the breaking of (==) => (=), since "nan == nan"
evaluates to true and "nan = nan" evaluates to false.

These are pretty weird and unpleasant surprises, and now that I've been
bitten by them I'm eager to avoid them in the future.  Hence my desire for
a polymorphic equality function that doesn't change it's behavior when
applied to floats.

y


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-14 20:52   ` Yaron Minsky
@ 2003-10-14 23:43     ` skaller
  2003-10-16 17:29       ` Hendrik Tews
  0 siblings, 1 reply; 18+ messages in thread
From: skaller @ 2003-10-14 23:43 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: caml-list

On Wed, 2003-10-15 at 06:52, Yaron Minsky wrote:

> The second weirdness is the breaking of (==) => (=), since "nan == nan"
> evaluates to true and "nan = nan" evaluates to false.

The problem here is IEEE semantics, not Ocaml.

The idea that x = x isn't universally true is 
mathemtically absurd.

One solution is to define a new float specific
IEEE conforming equality comparator 

	iEEE_eq : float -> float -> bool

and change the semantics of = to be mathematically
sound with

	Nan = Nan ==> true

but possibly more expensive to evaluate.

This means that polymorphic comparisons agree with
monomorphic ones, and leaves it up to the numerical
programmer to use the monomorphic iEEE_eq comparison 
it is needed. [Possibly the iEEE_eq function can be
given an infix symbol?]



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-14 14:37 [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
  2003-10-14 14:56 ` Yaron Minsky
@ 2003-10-16 13:16 ` Xavier Leroy
  2003-10-16 14:01   ` Yaron Minsky
                     ` (2 more replies)
  2003-10-16 23:55 ` [Caml-list] " Jed Davis
  2 siblings, 3 replies; 18+ messages in thread
From: Xavier Leroy @ 2003-10-16 13:16 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: caml-list

> Now here's the weird bit.  I decided I wanted a polymorphic comparison
> that wouldn't have this problem.  But this is a little harder than it
> seems, since it turns out that specialized float version of equality is
> different from the polymorphic version.

Yes, it's a long-standing bug for which we haven't yet a good
solution.  More exactly, there are two problematic solutions:

1- Fix polymorphic equality so that it behaves like IEEE equality on floats,
i.e. it always returns false when one of its arguments is NaN.
The problem is that this breaks the implication
        x == y  imply  x = y
and thus the current implementation of polymorphic equality needs to
be made less efficient.  Currently, x = y starts by testing x == y
and returns true if the pointer equality holds.  But this could be the
wrong result according to the new specification, since x can contain
an NaN somewhere.  Hence, polymorphic equality would have to traverse
its two arguments even when they are physically the same.  The
performance impact of this change on real programs is unknown.

2- As J M Skaller proposed, change the behavior of polymorphic
equality and its version specialized to floats so that nan = nan
and nan <> x if x <> nan.  Similar changes need to be done on the
<>, <= and >= tests for consistency.  IEEE comparisons would then have to be
provided as separate primitives.  This preserves the implication
x == y ==> x = y.  But the machine code generated for =, <>, <= and >=
over floats will have to be a lot less efficient than it is now, since
all processors implement float comparisons as per IEEE.

Coming back to your proposed workaround:

> # let raw_min = min
> val raw_min : 'a -> 'a -> 'a = <fun>
> # let min x y =
>   if not (y = y) then y
>   else if not (x = x) then x
>   else raw_min x y
> ;;

A way to make this work would be to replace the "not (x = x)" tests
by calls to the following function (of type 'a -> bool):

let is_obj_nan x =
  Obj.tag (Obj.repr x) = Obj.double_tag &&
  (let f = (Obj.magic x : float) in not (f = f))

Not pretty, I agree.

- Xavier Leroy

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-16 13:16 ` Xavier Leroy
@ 2003-10-16 14:01   ` Yaron Minsky
  2003-10-17  9:26     ` [Caml-list] Test nan (was: Weird behavior with nan's and min/max) Christophe TROESTLER
  2003-10-16 21:40   ` [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
  2003-10-17 14:55   ` skaller
  2 siblings, 1 reply; 18+ messages in thread
From: Yaron Minsky @ 2003-10-16 14:01 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

Your explanation matches my general understanding of the bug, and why it's
hard to fix.  One thing that I think should be fixed, though, is the
documentation.  This is really a surprising little bug, and it would be
nice to have it mentioned in the documentation somewhere, perhaps as a
footnote of sorts to the definition of equality.

Here's a related question:  how to test if a float is nan efficiently?  I
know two ways: seeing if it's not equal to itself, and using
Pevasives.classify_float.  The performance difference is pretty
interesting.  Here are the performance results I got for 100,000
iterations.

Time for classify nan : 0.001205 secs
Time for classify norm: 0.001205 secs
Time for eqtest nan   : 0.093635 secs
Time for eqtest norm  : 0.000302 secs

I'm quite surprised that the equality test is so slow on nan's.  Is this
just a feature of x86 hardware?  Are there any other options for testing
for nan-ness?

y

>> Now here's the weird bit.  I decided I wanted a polymorphic comparison
>> that wouldn't have this problem.  But this is a little harder than it
>> seems, since it turns out that specialized float version of equality is
>> different from the polymorphic version.
>
> Yes, it's a long-standing bug for which we haven't yet a good
> solution.  More exactly, there are two problematic solutions:
>
> 1- Fix polymorphic equality so that it behaves like IEEE equality on
> floats,
> i.e. it always returns false when one of its arguments is NaN.
> The problem is that this breaks the implication
>         x == y  imply  x = y
> and thus the current implementation of polymorphic equality needs to
> be made less efficient.  Currently, x = y starts by testing x == y
> and returns true if the pointer equality holds.  But this could be the
> wrong result according to the new specification, since x can contain
> an NaN somewhere.  Hence, polymorphic equality would have to traverse
> its two arguments even when they are physically the same.  The
> performance impact of this change on real programs is unknown.
>
> 2- As J M Skaller proposed, change the behavior of polymorphic
> equality and its version specialized to floats so that nan = nan
> and nan <> x if x <> nan.  Similar changes need to be done on the
> <>, <= and >= tests for consistency.  IEEE comparisons would then have to
> be
> provided as separate primitives.  This preserves the implication
> x == y ==> x = y.  But the machine code generated for =, <>, <= and >=
> over floats will have to be a lot less efficient than it is now, since
> all processors implement float comparisons as per IEEE.
>
> Coming back to your proposed workaround:
>
>> # let raw_min = min
>> val raw_min : 'a -> 'a -> 'a = <fun>
>> # let min x y =
>>   if not (y = y) then y
>>   else if not (x = x) then x
>>   else raw_min x y
>> ;;
>
> A way to make this work would be to replace the "not (x = x)" tests
> by calls to the following function (of type 'a -> bool):
>
> let is_obj_nan x =
>   Obj.tag (Obj.repr x) = Obj.double_tag &&
>   (let f = (Obj.magic x : float) in not (f = f))
>
> Not pretty, I agree.
>
> - Xavier Leroy
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-14 23:43     ` skaller
@ 2003-10-16 17:29       ` Hendrik Tews
  0 siblings, 0 replies; 18+ messages in thread
From: Hendrik Tews @ 2003-10-16 17:29 UTC (permalink / raw)
  To: caml-list

skaller writes:
   Subject: Re: [Caml-list] Weird behavior with nan's and min/max
   
   The idea that x = x isn't universally true is 
   mathemtically absurd.
   
I don't think it has to do with mathematics. It has to do with
logic. While there is only one mathematic, there lots of logics
around. Some of those are totally sensible, still they do not let
you deduce x = x for all x. 

The prominent examples are logics that deal with undefined terms
and partial functions. In this field a popular approach is to use
existential equality: x = y is true iff both are defined and
equal. The advantage of this approach is that you don't need an
additional definedness predicate and (more importantly) the
equality relation is recursively enumerable (if you don't mess
things up in the rest of the logic). 

In this light, I think it might be absurd to have x = x
universally true, because sometimes you can't even tell if x = x
(because there is no algorithm that can decide it).
;-)

(However, most of the time I use higher-order logics in which 
x = x is always true.)

Bye,

Hendrik Tews

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-16 13:16 ` Xavier Leroy
  2003-10-16 14:01   ` Yaron Minsky
@ 2003-10-16 21:40   ` Yaron Minsky
  2003-10-16 21:50     ` Yaron Minsky
  2003-10-16 22:52     ` Damien Doligez
  2003-10-17 14:55   ` skaller
  2 siblings, 2 replies; 18+ messages in thread
From: Yaron Minsky @ 2003-10-16 21:40 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

I tried a solution based on Xavier's suggestion, and it now looks to me
like Xavier's suggsetion (or my implementation) is unsafe.  Here's the
code I tried:

let is_obj_nan x =
  Obj.tag (Obj.repr x) = Obj.double_tag &&
  (let f = (Obj.magic x : float) in not (f = f))

let min x y =
  if is_obj_nan x then x
  else if is_obj_nan y then y
  else Pervasives.min x y

let max x y =
  if is_obj_nan x then x
  else if is_obj_nan y then y
  else Pervasives.max x y;;

The resulting code segfaulted on me, and the segfault went away when I
went back to the ordinary min and max.  Does anyone have a thought on
this?  Is this use of Obj safe or not?

I'm still trying to debug the actual location of the segfault, but the
lack of stacktraces makes it a bit harder....

y

>> Now here's the weird bit.  I decided I wanted a polymorphic comparison
>> that wouldn't have this problem.  But this is a little harder than it
>> seems, since it turns out that specialized float version of equality is
>> different from the polymorphic version.
>
> Yes, it's a long-standing bug for which we haven't yet a good
> solution.  More exactly, there are two problematic solutions:
>
> 1- Fix polymorphic equality so that it behaves like IEEE equality on
> floats,
> i.e. it always returns false when one of its arguments is NaN.
> The problem is that this breaks the implication
>         x == y  imply  x = y
> and thus the current implementation of polymorphic equality needs to
> be made less efficient.  Currently, x = y starts by testing x == y
> and returns true if the pointer equality holds.  But this could be the
> wrong result according to the new specification, since x can contain
> an NaN somewhere.  Hence, polymorphic equality would have to traverse
> its two arguments even when they are physically the same.  The
> performance impact of this change on real programs is unknown.
>
> 2- As J M Skaller proposed, change the behavior of polymorphic
> equality and its version specialized to floats so that nan = nan
> and nan <> x if x <> nan.  Similar changes need to be done on the
> <>, <= and >= tests for consistency.  IEEE comparisons would then have to
> be
> provided as separate primitives.  This preserves the implication
> x == y ==> x = y.  But the machine code generated for =, <>, <= and >=
> over floats will have to be a lot less efficient than it is now, since
> all processors implement float comparisons as per IEEE.
>
> Coming back to your proposed workaround:
>
>> # let raw_min = min
>> val raw_min : 'a -> 'a -> 'a = <fun>
>> # let min x y =
>>   if not (y = y) then y
>>   else if not (x = x) then x
>>   else raw_min x y
>> ;;
>
> A way to make this work would be to replace the "not (x = x)" tests
> by calls to the following function (of type 'a -> bool):
>
> let is_obj_nan x =
>   Obj.tag (Obj.repr x) = Obj.double_tag &&
>   (let f = (Obj.magic x : float) in not (f = f))
>
> Not pretty, I agree.
>
> - Xavier Leroy
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-16 21:40   ` [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
@ 2003-10-16 21:50     ` Yaron Minsky
  2003-10-16 22:52     ` Damien Doligez
  1 sibling, 0 replies; 18+ messages in thread
From: Yaron Minsky @ 2003-10-16 21:50 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: Xavier Leroy, caml-list

Well, finding the problem was a bit easier than I'd expected.

# min 3 4

causes a segfault.

> I tried a solution based on Xavier's suggestion, and it now looks to me
> like Xavier's suggsetion (or my implementation) is unsafe.  Here's the
> code I tried:
>
> let is_obj_nan x =
>   Obj.tag (Obj.repr x) = Obj.double_tag &&
>   (let f = (Obj.magic x : float) in not (f = f))
>
> let min x y =
>   if is_obj_nan x then x
>   else if is_obj_nan y then y
>   else Pervasives.min x y
>
> let max x y =
>   if is_obj_nan x then x
>   else if is_obj_nan y then y
>   else Pervasives.max x y;;
>
> The resulting code segfaulted on me, and the segfault went away when I
> went back to the ordinary min and max.  Does anyone have a thought on
> this?  Is this use of Obj safe or not?
>
> I'm still trying to debug the actual location of the segfault, but the
> lack of stacktraces makes it a bit harder....
>
> y
>
>>> Now here's the weird bit.  I decided I wanted a polymorphic comparison
>>> that wouldn't have this problem.  But this is a little harder than it
>>> seems, since it turns out that specialized float version of equality is
>>> different from the polymorphic version.
>>
>> Yes, it's a long-standing bug for which we haven't yet a good
>> solution.  More exactly, there are two problematic solutions:
>>
>> 1- Fix polymorphic equality so that it behaves like IEEE equality on
>> floats,
>> i.e. it always returns false when one of its arguments is NaN.
>> The problem is that this breaks the implication
>>         x == y  imply  x = y
>> and thus the current implementation of polymorphic equality needs to
>> be made less efficient.  Currently, x = y starts by testing x == y
>> and returns true if the pointer equality holds.  But this could be the
>> wrong result according to the new specification, since x can contain
>> an NaN somewhere.  Hence, polymorphic equality would have to traverse
>> its two arguments even when they are physically the same.  The
>> performance impact of this change on real programs is unknown.
>>
>> 2- As J M Skaller proposed, change the behavior of polymorphic
>> equality and its version specialized to floats so that nan = nan
>> and nan <> x if x <> nan.  Similar changes need to be done on the
>> <>, <= and >= tests for consistency.  IEEE comparisons would then have
>> to
>> be
>> provided as separate primitives.  This preserves the implication
>> x == y ==> x = y.  But the machine code generated for =, <>, <= and >=
>> over floats will have to be a lot less efficient than it is now, since
>> all processors implement float comparisons as per IEEE.
>>
>> Coming back to your proposed workaround:
>>
>>> # let raw_min = min
>>> val raw_min : 'a -> 'a -> 'a = <fun>
>>> # let min x y =
>>>   if not (y = y) then y
>>>   else if not (x = x) then x
>>>   else raw_min x y
>>> ;;
>>
>> A way to make this work would be to replace the "not (x = x)" tests
>> by calls to the following function (of type 'a -> bool):
>>
>> let is_obj_nan x =
>>   Obj.tag (Obj.repr x) = Obj.double_tag &&
>>   (let f = (Obj.magic x : float) in not (f = f))
>>
>> Not pretty, I agree.
>>
>> - Xavier Leroy
>>
>> -------------------
>> To unsubscribe, mail caml-list-request@inria.fr Archives:
>> http://caml.inria.fr
>> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
>> http://caml.inria.fr/FAQ/
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-16 21:40   ` [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
  2003-10-16 21:50     ` Yaron Minsky
@ 2003-10-16 22:52     ` Damien Doligez
  1 sibling, 0 replies; 18+ messages in thread
From: Damien Doligez @ 2003-10-16 22:52 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: caml-list

On Thursday, October 16, 2003, at 11:40 PM, Yaron Minsky wrote:

> let is_obj_nan x =
>   Obj.tag (Obj.repr x) = Obj.double_tag &&
>   (let f = (Obj.magic x : float) in not (f = f))
[...]
> The resulting code segfaulted on me, and the segfault went away when I
> went back to the ordinary min and max.  Does anyone have a thought on
> this?  Is this use of Obj safe or not?

The problem is that the argument of Obj.tag must be a pointer value
that lives in the heap.  A pointer value answers false to Obj.is_int,
but you have no way to test for heap-allocated values.

This is going to change soon because I am fixing the bug found by
Jacques with float lazy arrays, and in the process I will extend
Obj.tag to give meaningful answers for ints and non-heap-allocated
values.

In the meantime, you can use the following code, but it might still
fail in some rare cases when applied to non-heap-allocated values
(I/O channels for example):

let is_obj_nan x =
   not (Obj.is_int (Obj.repr x)) &&
   Obj.tag (Obj.repr x) = Obj.double_tag &&
   (let f = (Obj.magic x : float) in not (f = f))
;;

-- Damien

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Caml-list] Re: Weird behavior with nan's and min/max
  2003-10-14 14:37 [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
  2003-10-14 14:56 ` Yaron Minsky
  2003-10-16 13:16 ` Xavier Leroy
@ 2003-10-16 23:55 ` Jed Davis
  2 siblings, 0 replies; 18+ messages in thread
From: Jed Davis @ 2003-10-16 23:55 UTC (permalink / raw)
  To: caml-list

"Yaron Minsky" <yminsky@cs.cornell.edu> writes:

> since it turns out that specialized float version of equality is
> different from the polymorphic version.

Here's an especially fun example:

# nan = nan;;
- : bool = false
# let (=) = (=);;
val ( = ) : 'a -> 'a -> bool = <fun>
# nan = nan;;
- : bool = true



-- 
Jed Davis <jldavis@cs.oberlin.edu>  Selling of self: http://panix.com/~jdev/rs/
<jdev@panix.com>  PGP<-finger A098:903E:9B9A:DEF4:168F:AA09:BF07:807E:F336:59F9
\   "But life wasn't yes-no, on-off.  Life was shades of gray, and rainbows
/\   not in the order of the spectrum."  -- L. E. Modesitt, Jr., _Adiamante_

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Caml-list] Test nan (was: Weird behavior with nan's and min/max)
  2003-10-16 14:01   ` Yaron Minsky
@ 2003-10-17  9:26     ` Christophe TROESTLER
  0 siblings, 0 replies; 18+ messages in thread
From: Christophe TROESTLER @ 2003-10-17  9:26 UTC (permalink / raw)
  To: yminsky; +Cc: xavier.leroy, caml-list

On Thu, 16 Oct 2003, "Yaron Minsky" <yminsky@cs.cornell.edu> wrote:
> 
> how to test if a float is nan efficiently?

Why not add a primitive is_nan (and while we are at it is_finite)?

ChriS

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-16 13:16 ` Xavier Leroy
  2003-10-16 14:01   ` Yaron Minsky
  2003-10-16 21:40   ` [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
@ 2003-10-17 14:55   ` skaller
  2003-10-17 15:14     ` Floating point exceptions (Was Re: [Caml-list] Weird behavior with nan's and min/max) Yaron Minsky
  2003-10-17 23:55     ` [Caml-list] Weird behavior with nan's and min/max Yaron M. Minsky
  2 siblings, 2 replies; 18+ messages in thread
From: skaller @ 2003-10-17 14:55 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: Yaron Minsky, caml-list

On Thu, 2003-10-16 at 23:16, Xavier Leroy wrote:

> 1- Fix polymorphic equality so that it behaves like IEEE equality on floats,

> 2- As J M Skaller proposed, change the behavior of polymorphic
> equality 

Doesn't the polymorphic comparison have to be a total order?


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Floating point exceptions (Was Re: [Caml-list] Weird behavior with  nan's and min/max)
  2003-10-17 14:55   ` skaller
@ 2003-10-17 15:14     ` Yaron Minsky
  2003-10-17 23:55     ` [Caml-list] Weird behavior with nan's and min/max Yaron M. Minsky
  1 sibling, 0 replies; 18+ messages in thread
From: Yaron Minsky @ 2003-10-17 15:14 UTC (permalink / raw)
  To: caml-list

Here's another question:  is it possible to catch floating point
exceptions such as division by zero?  It seems like that might be another
way of dealing with this.  I thought catching SIGFPE would do it, but I
tried and I couldn't seem to get it triggered.  Is it possible to convert
floating point exceptions to ocaml exceptions?

y

> On Thu, 2003-10-16 at 23:16, Xavier Leroy wrote:
>
>> 1- Fix polymorphic equality so that it behaves like IEEE equality on
>> floats,
>
>> 2- As J M Skaller proposed, change the behavior of polymorphic
>> equality
>
> Doesn't the polymorphic comparison have to be a total order?
>
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-17 14:55   ` skaller
  2003-10-17 15:14     ` Floating point exceptions (Was Re: [Caml-list] Weird behavior with nan's and min/max) Yaron Minsky
@ 2003-10-17 23:55     ` Yaron M. Minsky
  2003-10-20 13:29       ` Xavier Leroy
  1 sibling, 1 reply; 18+ messages in thread
From: Yaron M. Minsky @ 2003-10-17 23:55 UTC (permalink / raw)
  To: Caml List

On Fri, 2003-10-17 at 10:55, skaller wrote:
> On Thu, 2003-10-16 at 23:16, Xavier Leroy wrote:
> 
> > 1- Fix polymorphic equality so that it behaves like IEEE equality on floats,
> 
> > 2- As J M Skaller proposed, change the behavior of polymorphic
> > equality 
> 
> Doesn't the polymorphic comparison have to be a total order?

This kind of wigs me out too.  For example, do the set and map data
structures depend on this total order property?  What happens when I
stick in a data structure which contains some floats somewhere in it,
and some of those floats are nan's?  Does the data structure continue to
work at all?  It totally wigs me out.

I wish there was some sensible way around it.  Probably the thing I
would like best is for calculations that produce nans to throw
exceptions.  But from what I've heard so far, this doesn't appear to be
possible.  Oh well.

y

-- 
|--------/            Yaron M. Minsky              \--------|
|--------\ http://www.cs.cornell.edu/home/yminsky/ /--------|

Open PGP --- KeyID B1FFD916 (new key as of Dec 4th)
Fingerprint: 5BF6 83E1 0CE3 1043 95D8 F8D5 9F12 B3A9 B1FF D916



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-17 23:55     ` [Caml-list] Weird behavior with nan's and min/max Yaron M. Minsky
@ 2003-10-20 13:29       ` Xavier Leroy
  2003-10-20 13:43         ` Yaron Minsky
  0 siblings, 1 reply; 18+ messages in thread
From: Xavier Leroy @ 2003-10-20 13:29 UTC (permalink / raw)
  To: Yaron M. Minsky; +Cc: Caml List

> > Doesn't the polymorphic comparison have to be a total order?

Pervasive.compare must be a total order, so it would need to throw an
exception if its arguments are unordered (e.g. one is "nan").
The other comparisons (=, <, etc) could implement a partial order,
returning "false" in the "unordered" case (except for <>, which should
return "true" in this case).

> This kind of wigs me out too.  For example, do the set and map data
> structures depend on this total order property?  What happens when I
> stick in a data structure which contains some floats somewhere in it,
> and some of those floats are nan's?  Does the data structure continue to
> work at all?  It totally wigs me out.

Sets and maps require a total order, so, yes, in the current
implementation, strange things can happen with "nan" used as set
elements or map keys.  Again, throwing an "unordered" exception in
Pervasives.compare would avoid the problem.  

Note, however, that it doesn't make much sense to use floats as set
elements or map keys, due to the inherently approximate nature of floats.
E.g. does the set {1.0; 1.0+.epsilon} have 1 or 2 elements?

> I wish there was some sensible way around it.  Probably the thing I
> would like best is for calculations that produce nans to throw
> exceptions.  But from what I've heard so far, this doesn't appear to be
> possible.

The IEEE standard specifies both behaviors: return nan or cause a
floating-point trap, and says that there should be an API to choose
the desired behavior.  Most processors implement the two behaviors,
controlled by some status bit somewhere.

The first problem is that there is no standard C API to select the
desired behavior (even ISO C 99 isn't terribly clear on this).  So,
everyone stays in the "nans, no traps" mode.

> Here's another question:  is it possible to catch floating point
> exceptions such as division by zero?  It seems like that might be another
> way of dealing with this.  I thought catching SIGFPE would do it, but I
> tried and I couldn't seem to get it triggered.  Is it possible to convert
> floating point exceptions to ocaml exceptions?

That's the second problem.  Trapping a synchronous signal (such as
SIGFPE) and turning it into a Caml exception is quite hard and
non-portable.  Caml manages to deal with asynchronous signals by
delaying their delivery until a safe point is reached, but obviously
this doesn't work for synchronous, program-generated signals.  
E.g. what to do if the SIGFPE comes from C code running in "blocking
section" mode?

- Xavier Leroy

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-20 13:29       ` Xavier Leroy
@ 2003-10-20 13:43         ` Yaron Minsky
  2003-10-20 14:24           ` Xavier Leroy
  0 siblings, 1 reply; 18+ messages in thread
From: Yaron Minsky @ 2003-10-20 13:43 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: Caml List

>> > Doesn't the polymorphic comparison have to be a total order?
>
> Pervasive.compare must be a total order, so it would need to throw an
> exception if its arguments are unordered (e.g. one is "nan").
> The other comparisons (=, <, etc) could implement a partial order,
> returning "false" in the "unordered" case (except for <>, which should
> return "true" in this case).

OK, so this makes me feel a little better -- turns out the polymorphic
compare is a total order.  There is some remaining weirdness though (as
one would expect), in that the polymorphic nan is equal to everything
else.  As a strange result, if you create a Set from the polymorphic
compare, you get the following weird result:

# Set.elements (Set.of_list [Some 3.; Some nan]);;
- : float option list = [Some 3.]
# Set.elements (Set.of_list [Some nan; Some 3.]);;
- : float option list = [Some nan]

I suppose it's too late to change this kind of behavior, but wouldn't it
make more sense for nan to be different from everything but itself?  Maybe
make nan the smallest thing bigger than -infinitiy, or the largest thing
smaller than infinity?  It's not perfect, but it seems better than making
it equal to everything.

By the way, in my context, there are plenty of times where it makes sense
to have sets and maps of things that contain floating point numbers
(although rarely of floating point numbers proper.)  In practice, I rely
on equality holding only when two floating point numbers were derived in
precisely the same way or were copies of each other.  But it does come up
quite a bit.

y

y

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Weird behavior with nan's and min/max
  2003-10-20 13:43         ` Yaron Minsky
@ 2003-10-20 14:24           ` Xavier Leroy
  0 siblings, 0 replies; 18+ messages in thread
From: Xavier Leroy @ 2003-10-20 14:24 UTC (permalink / raw)
  To: Yaron Minsky; +Cc: Caml List

> > Pervasive.compare must be a total order, so it would need to throw an
> > exception if its arguments are unordered (e.g. one is "nan").
> > The other comparisons (=, <, etc) could implement a partial order,
> > returning "false" in the "unordered" case (except for <>, which should
> > return "true" in this case).
> 
> OK, so this makes me feel a little better -- turns out the polymorphic
> compare is a total order.

I should have been clearer: "would need to..." implies that the
current implementation doesn't do this; only the alternate
implementations that I suggested in a previous message could (and
should) behave this way.

> There is some remaining weirdness though (as
> one would expect), in that the polymorphic nan is equal to everything
> else.

Again, it's a problem (the problem?) with the current implementation,
and it needs fixing.

> I suppose it's too late to change this kind of behavior, but wouldn't it
> make more sense for nan to be different from everything but itself?

Yes, that would be much better.  According to IEEE, nan should even be
different from itself...

> Maybe make nan the smallest thing bigger than -infinitiy, or the
> largest thing smaller than infinity?

This isn't what IEEE does.

> By the way, in my context, there are plenty of times where it makes sense
> to have sets and maps of things that contain floating point numbers
> (although rarely of floating point numbers proper.)  

I'd be interested in some examples, but we can continue this
discussion off the list.

- Xavier Leroy

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2003-10-20 14:24 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 14:37 [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
2003-10-14 14:56 ` Yaron Minsky
2003-10-14 20:52   ` Yaron Minsky
2003-10-14 23:43     ` skaller
2003-10-16 17:29       ` Hendrik Tews
2003-10-16 13:16 ` Xavier Leroy
2003-10-16 14:01   ` Yaron Minsky
2003-10-17  9:26     ` [Caml-list] Test nan (was: Weird behavior with nan's and min/max) Christophe TROESTLER
2003-10-16 21:40   ` [Caml-list] Weird behavior with nan's and min/max Yaron Minsky
2003-10-16 21:50     ` Yaron Minsky
2003-10-16 22:52     ` Damien Doligez
2003-10-17 14:55   ` skaller
2003-10-17 15:14     ` Floating point exceptions (Was Re: [Caml-list] Weird behavior with nan's and min/max) Yaron Minsky
2003-10-17 23:55     ` [Caml-list] Weird behavior with nan's and min/max Yaron M. Minsky
2003-10-20 13:29       ` Xavier Leroy
2003-10-20 13:43         ` Yaron Minsky
2003-10-20 14:24           ` Xavier Leroy
2003-10-16 23:55 ` [Caml-list] " Jed Davis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).