Clojure Q&A - Recent questions tagged math
https://ask.clojure.org/index.php/tag/math
Some corner cases that might be considered bugs in Ratio implementation
https://ask.clojure.org/index.php/11521/some-corner-cases-that-might-considered-ratio-implementation
<p>I was looking through the new <code>clojure.core/abs</code> implementation on type Ratio, and it seemed that there is an assumption in the code that uses the internal details of type clojure.lang.Ratio that the denominator is always positive (e.g. see the definitions of isNeg and isPos methods for type Ratio).</p>
<p>I started looking for cases where that assumption might be violated, and found the following, all of which might be distinctive to values of type Ratio produced by an expression with Long/MIN_VALUE as the denominator and an integer with type Long or smaller as the numerator:</p>
<pre><code>$ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.11.0-alpha4"}}}'
Clojure 1.11.0-alpha4
user=> (/ 1 Long/MIN_VALUE)
-1/-9223372036854775808
user=> (< (/ 1 Long/MIN_VALUE) 0) ;; This gives correct numerical answer
true
user=> (< (* 1 (/ 1 Long/MIN_VALUE)) 0) ;; This does not
false
user=> (abs (/ 1 Long/MIN_VALUE)) ;; Gives incorrect numerical answer
1/-9223372036854775808
user=> (< (abs (/ 1 Long/MIN_VALUE)) 0) ;; correct numerical answer
false
user=> (< (* 1 (abs (/ 1 Long/MIN_VALUE))) 0) ;; incorrect numerical answer
true
</code></pre>
<p>I have carefully checked other occurrences of Ratio in source file Numbers.java in Clojure's implementation, and as far as I can tell the only issue is with the method named divide in the LongOps class. If that method avoided this problem by checking for the special case when the numerator and/or denominator is equal to Long/MIN_VALUE and behaved a little differently in that case, I do not see any other bugs.</p>
<p>Here is another issue if the numerator is equal to Long/MIN_VALUE, where the root cause is in the same LongOps divide method:</p>
<pre><code>user=> (/ Long/MIN_VALUE -3) ;; should return positive value, but returns negative value
-9223372036854775808/3
user=> (< (/ Long/MIN_VALUE -3) 0)
true
</code></pre>
Clojurehttps://ask.clojure.org/index.php/11521/some-corner-cases-that-might-considered-ratio-implementationSun, 30 Jan 2022 02:24:18 +0000Should other math wrappers be considered?
https://ask.clojure.org/index.php/11516/should-other-math-wrappers-be-considered
<p>With the <code>java.lang.Math</code> operations all being wrapped, then is it also desirable to do the same with the operations static methods on <code>Double</code> and <code>Long</code>?</p>
<p>Some of these functions have simple Clojure(Script) implementations. For instance, <code>Double/isNaN</code> can be achieved with <code>#(identical? ##NaN %)</code> but it seems that if the language works with values like <code>##NaN</code>, then there should be a built-in way of recognizing it. (I note that some people may not realize that <code>#(= ##NaN %)</code> will not work).</p>
<p>Each of these functions can also be implemented in ClojureScript. This was demonstrated while reimplementing the <code>clojure.math</code> namespace for ClojureScript, since many of these methods from Long and Double were needed.</p>
ClojureScripthttps://ask.clojure.org/index.php/11516/should-other-math-wrappers-be-consideredWed, 26 Jan 2022 19:35:54 +0000