javascript-bignum icon indicating copy to clipboard operation
javascript-bignum copied to clipboard

Negative inexact raised to a power

Open ghost opened this issue 10 years ago • 2 comments

I believe the following illustrates some undesirable behavior.

   var sn = SchemeNumber;
   var a = sn('#i-1');
   var p = sn('1');
   var result = sn.fn['expt'](a, p);
   console.log(a + "^" + p + " = " + result);
   console.log(a + "^" + p + " = " + result.toString());

Raising an inexact negative number to a (non-complex) power results in a complex number. And, printing this number gives NaN unless the toString method is explicitly called.

ghost avatar Jan 25 '15 03:01 ghost

I agree the behavior is undesirable: a real raised to an exact integer should result in a real. Here is a patch to master. I do not have time to test for regressions, so I hesitate to push it.

diff --git a/schemeNumber.js b/schemeNumber.js
index b44fc24..b089623 100644
--- a/schemeNumber.js
+++ b/schemeNumber.js
@@ -3642,6 +3642,7 @@ function implementPluginLibrary(plugins) {
     // Functions to be provided by number implementations.
     var nativeToExactInteger, divideReducedNotByOne;
     var exactRectangular, inexactRectangular;
+    var nativeToInexact;

     // Imports from ECMAScript.
     var g                = plugins.get("es5globals");
@@ -3678,6 +3679,7 @@ function implementPluginLibrary(plugins) {
         divideReducedNotByOne    = plugins.get("divideReducedNotByOne");
         exactRectangular         = plugins.get("exactRectangular");
         inexactRectangular       = plugins.get("inexactRectangular");
+        nativeToInexact          = plugins.get("nativeToInexact");

         ZERO                     = plugins.get("ZERO");
         ONE                      = plugins.get("ONE");
@@ -3970,6 +3972,8 @@ function implementPluginLibrary(plugins) {
     function complex_or_exact_expt(n) {
         if (isExact(this))
             return expt_N_EI_fn(this, n);
+        if (isReal(this))
+            return nativeToInexact(Math_pow(this, n));
         return Complex_expt_fn(this, n);
     }
     function tan_via_divide_sin_cos() {

As for having to call toString() explicitly after the + operator, that is unavoidable. I would write String(result) instead of result.toString() to handle nulls.

jtobey avatar Jan 25 '15 16:01 jtobey

Applied the patch and did'nt see any regressions in my (indirect and insufficient) set of tests. Thanks for your work!

ghost avatar Jan 26 '15 04:01 ghost