Details
-
Type:
Defect
-
Status:
Closed
-
Priority:
Minor
-
Resolution: Completed
-
Affects Version/s: Release 1.3
-
Fix Version/s: Release 1.4
-
Component/s: None
-
Labels:None
-
Patch:Code and Test
-
Approval:Ok
Description
The min and max functions in clojure.core behave unpredictably when one or more of their arguments is Float/NaN or Double/NaN. This is because the current implementation assumes that > provides a total ordering, but this is not the case when NaN is added to the mix. This is an unfortunate fact of life when dealing with IEEE floating point numbers.
See also the recent mailing list thread "clojure.core/max and NaN".
May be related to issue CLJ-738.
It seems to me that there are four approaches one might take to address this.
1 Document current behavior as undefined
This requires no changes in the implementation, but it doesn't strike me as a desirable resolution. Why unnecessarily codify clearly confusing behavior?
2 Make NaN contagious
Define min and max to return NaN if and only if at least one of their arguments is NaN. This seems most in keeping with the (admittedly perverse) behavior of NaN as specified.
See JLS 4.2.4 Floating Point Operations:
3 Let min and max ignore NaN arguments
This means that (min a NaN b) would be exactly equivalent to (min a b). It would further imply that (min NaN) would be equivalent to (min), which currently throws an exception.
4 Let NaN cause min and max to throw an exception
Currently min and max throw an exception if given arguments that are not Numeric. One might plausibly argue that NaN is not numeric.
1 Document current behavior as undefined
This requires no changes in the implementation, but it doesn't strike me as a desirable resolution. Why unnecessarily codify clearly confusing behavior?2 Make NaN contagious
Define min and max to return NaN if and only if at least one of their arguments is NaN. This seems most in keeping with the (admittedly perverse) behavior of NaN as specified. See JLS 4.2.4 Floating Point Operations:3 Let min and max ignore NaN arguments
This means that (min a NaN b) would be exactly equivalent to (min a b). It would further imply that (min NaN) would be equivalent to (min), which currently throws an exception.4 Let NaN cause min and max to throw an exception
Currently min and max throw an exception if given arguments that are not Numeric. One might plausibly argue that NaN is not numeric.