<!-- 
RSS generated by JIRA (4.4#649-r158309) at Sat May 25 08:15:55 CDT 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://dev.clojure.org/jira/si/jira.issueviews:issue-xml/CLJ-738/CLJ-738.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Clojure JIRA</title>
    <link>http://dev.clojure.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>4.4</version>
        <build-number>649</build-number>
        <build-date>25-07-2011</build-date>
    </build-info>

<item>
            <title>[CLJ-738] &lt;= is incorrect when args include Double/NaN</title>
                <link>http://dev.clojure.org/jira/browse/CLJ-738</link>
                <project id="10010" key="CLJ">Clojure</project>
                        <description>&lt;p&gt;user&amp;gt; (&amp;lt;= 10 Double/NaN 1)&lt;br/&gt;
true&lt;/p&gt;

&lt;p&gt;(on both 1.2 and 1.3 alpha 5).  &lt;/p&gt;</description>
                <environment>Mac OS X, Java 6</environment>
            <key id="14352">CLJ-738</key>
            <summary>&lt;= is incorrect when args include Double/NaN</summary>
                <type id="1" iconUrl="http://dev.clojure.org/jira/images/icons/bug.gif">Defect</type>
                                <priority id="4" iconUrl="http://dev.clojure.org/jira/images/icons/priority_minor.gif">Minor</priority>
                    <status id="6" iconUrl="http://dev.clojure.org/jira/images/icons/status_closed.gif">Closed</status>
                    <resolution id="1">Completed</resolution>
                                <assignee username="lvanderhart">Luke VanderHart</assignee>
                                <reporter username="jawolfe">Jason Wolfe</reporter>
                        <labels>
                    </labels>
                <created>Mon, 14 Feb 2011 19:07:09 -0600</created>
                <updated>Fri, 1 Mar 2013 12:47:10 -0600</updated>
                    <resolved>Fri, 26 Aug 2011 11:35:55 -0500</resolved>
                            <version>Release 1.3</version>
                                <fixVersion>Release 1.3</fixVersion>
                                        <due></due>
                    <votes>1</votes>
                        <watches>4</watches>
                        <comments>
                    <comment id="26217" author="jawolfe" created="Mon, 14 Feb 2011 19:18:05 -0600"  >&lt;p&gt;The source of the issue seems to be incorrect treatment of boxed NaN:&lt;/p&gt;

&lt;p&gt;user&amp;gt; (&amp;lt;= 1000 (Double. Double/NaN))&lt;br/&gt;
true&lt;br/&gt;
user&amp;gt; (&amp;lt;= 1000 (double Double/NaN))&lt;br/&gt;
false&lt;/p&gt;</comment>
                    <comment id="26251" author="ataggart" created="Mon, 28 Feb 2011 23:14:30 -0600"  >&lt;p&gt;Primitive comparisons use java&apos;s primitive operators directly, which always return false for NaN, even when testing equality between two NaNs.&lt;/p&gt;

&lt;p&gt;In clojure, Number comparisons are all logical variations around calls to Numbers.Ops.lt(Number, Number).  So a call to &lt;tt&gt;(&amp;lt;= x y)&lt;/tt&gt; is actually a call to &lt;tt&gt;(not (&amp;lt; y x))&lt;/tt&gt;, which eventually uses the primitive &lt;tt&gt;&amp;lt;&lt;/tt&gt; operator.  Alas that logical premise doesn&apos;t hold when dealing with NaN:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;user=&amp;gt; (&amp;lt;= 1 Double/NaN)
false
user=&amp;gt; (not (&amp;lt; Double/NaN 1))
true
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the bug is not that boxed NaN is treated incorrectly, but rather:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;user&amp;gt; (&amp;lt;= 1000 (Double. Double/NaN)) ; becomes !(NaN &amp;lt; 1000) 
true
user&amp;gt; (&amp;lt;= 1000 (double Double/NaN))  ; becomes (1000 &amp;lt;= NaN)
false
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In the original example, since there are more than two args, the primitive looking args were boxed:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;user=&amp;gt; (&amp;lt;= 10 Double/NaN 1) ; equivalent to logical-and of the following
true
user=&amp;gt; (&amp;lt;= 10 (Double. Double/NaN))  ; becomes !(NaN &amp;lt; 10)
true
user=&amp;gt; (&amp;lt;= (Double. Double/NaN) 1)   ; becomes !(1 &amp;lt; NaN)
true
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note however that java object comparisons for NaNs behave differently: NaN is the largest Double, and NaNs equal each other (see the &lt;a href=&quot;http://download.oracle.com/javase/6/docs/api/java/lang/Double.html#compareTo(java.lang.Double)&quot;&gt;javadoc&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;If we make object NaN comparisons always return false, we would need to add the rest of the comparison methods to &lt;tt&gt;Numbers.Ops&lt;/tt&gt;.  Yet doing so could also make collection sorting algorithms behave oddly, deviating from sorting written in java. Besides, &lt;tt&gt;(= NaN NaN) =&amp;gt; false&lt;/tt&gt; is annoying.&lt;/p&gt;

&lt;p&gt;Clojure already throws out the notion of error-free dividing by zero (which for doubles would otherwise result in NaN or Infinity, depending on the dividend).  Perhaps we could similarly error on NaNs passed to clojure numeric ops.  They seem to be more trouble than they&apos;re worth.  That said, people smarter than me thought they were useful.&lt;/p&gt;

&lt;p&gt;Then there&apos;s that -0.0 nonsense...&lt;/p&gt;</comment>
                    <comment id="26314" author="jks" created="Sat, 19 Mar 2011 15:02:14 -0500"  >&lt;p&gt;On current master, &lt;tt&gt;(&amp;lt;= x y)&lt;/tt&gt; seems to be special-cased by the compiler, but when &lt;tt&gt;&amp;lt;=&lt;/tt&gt; is called dynamically, the bug is still there:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;user=&amp;gt; (&amp;lt;= 1 Float/NaN)
false
user=&amp;gt; (let [op &amp;lt;=] (op 1 Float/NaN))
true
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Since &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-354&quot; title=&quot;&amp;lt;= and &amp;gt;= comparisons against NaN return true&quot;&gt;&lt;del&gt;CLJ-354&lt;/del&gt;&lt;/a&gt; got marked &quot;Completed&quot;, perhaps there was an attempt to fix this.&lt;/p&gt;</comment>
                    <comment id="26317" author="ataggart" created="Sat, 19 Mar 2011 18:45:55 -0500"  >&lt;p&gt;Using &lt;tt&gt;let&lt;/tt&gt; forces calling &lt;tt&gt;&amp;lt;=&lt;/tt&gt; as a function rather than inlining &lt;tt&gt;Numbers/lte&lt;/tt&gt;, which means the args are treated as objects not primitives, thus the different behaviour as I discussed earlier.&lt;/p&gt;</comment>
                    <comment id="26537" author="aaron" created="Tue, 28 Jun 2011 18:28:31 -0500"  >&lt;p&gt;Rich, what should the behavior be?&lt;/p&gt;</comment>
                    <comment id="26543" author="jks" created="Wed, 29 Jun 2011 01:22:26 -0500"  >&lt;p&gt;My suggestion for the behavior is to follow Java (Java Language Specification &#167;15.20.1) and IEEE 754. The java.sun.com site seems to be down right now, but here&apos;s a Google cache link:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://webcache.googleusercontent.com/search?q=cache:http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.20.1&quot;&gt;http://webcache.googleusercontent.com/search?q=cache:http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.20.1&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="26671" author="richhickey" created="Fri, 29 Jul 2011 07:48:02 -0500"  >&lt;p&gt;It should work the same as primitive double in all cases&lt;/p&gt;</comment>
                    <comment id="26736" author="lvanderhart" created="Fri, 26 Aug 2011 11:33:15 -0500"  >&lt;p&gt;Added patches. The problem was that our logic for lte/gte depended on the fact that lte is equivalent to !gt. &lt;/p&gt;

&lt;p&gt;However, in Java, this assumption is invalid - any comparison involving NaN always yields false.&lt;/p&gt;

&lt;p&gt;The fix was to adding lte and gte methods to Numbers.Ops directly, rather than implementing everything in terms of lt. This was the only fix I could see that didn&apos;t incur the cost of runtime checks for NaN.&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="10321" name="738.diff" size="3932" author="lvanderhart" created="Fri, 26 Aug 2011 11:33:15 -0500" />
                    <attachment id="10322" name="738-tests.diff" size="2720" author="lvanderhart" created="Fri, 26 Aug 2011 11:33:15 -0500" />
                </attachments>
            <subtasks>
        </subtasks>
                <customfields>
                                                                                            <customfield id="customfield_10010" key="com.pyxis.greenhopper.jira:gh-global-rank">
                <customfieldname>Global Rank</customfieldname>
                <customfieldvalues>
                    
                </customfieldvalues>
            </customfield>
                                            <customfield id="customfield_10000" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                <customfieldname>Patch</customfieldname>
                <customfieldvalues>
                        <customfieldvalue key="10002">Code and Test</customfieldvalue>

                </customfieldvalues>
            </customfield>
                                                                                        </customfields>
    </item>
</channel>
</rss>