Repository: josdejong/mathjs
Pull request #674 (2016-06-20 18:28:24)

New function 'isNaN'
See #673 .


Patch:
diff --git a/lib/function/utils/index.js b/lib/function/utils/index.js
index b13e2b35e..393bdf93a 100644
--- a/lib/function/utils/index.js
+++ b/lib/function/utils/index.js
@@ -5,5 +5,6 @@ module.exports = [
   require('./isNumeric'),
   require('./isPositive'),
   require('./isZero'),
+  require('./isNaN'),
   require('./typeof')
 ];
diff --git a/lib/function/utils/isNaN.js b/lib/function/utils/isNaN.js
new file mode 100644
index 000000000..87a712051
--- /dev/null
+++ b/lib/function/utils/isNaN.js
@@ -0,0 +1,66 @@
+'use strict';
+
+var deepMap = require('../../utils/collection/deepMap');
+var number = require('../../utils/number');
+
+function factory (type, config, load, typed) {
+  /**
+   * Test whether a value is NaN (not a number).
+   * The function supports types `number`, `BigNumber`, `Fraction`, `Unit` and `Complex`.
+   *
+   * The function is evaluated element-wise in case of Array or Matrix input.
+   *
+   * Syntax:
+   *
+   *     math.isNaN(x)
+   *
+   * Examples:
+   *
+   *    math.isNaN(3);                     // returns false
+   *    math.isNaN(NaN);                   // returns true
+   *    math.isNaN(0);                     // returns false
+   *    math.isNaN(math.bignumber(NaN));   // returns true
+   *    math.isNaN(math.bignumber(0));     // returns false
+   *    math.isNaN(math.fraction(-2, 5));  // returns false
+   *    math.isNaN('-2');                  // returns false
+   *    math.isNaN([2, 0, -3, NaN]');      // returns [false, false, false, true]
+   *
+   * See also:
+   *
+   *    isNumeric, isNegative, isPositive, isZero, isInteger
+   *
+   * @param {number | BigNumber | Fraction | Unit | Array | Matrix} x  Value to be tested
+   * @return {boolean}  Returns true when `x` is NaN.
+   *                    Throws an error in case of an unknown data type.
+   */
+  var isNaN = typed('isNaN', {
+    'number': function (x) {
+      return Number.isNaN(x);
+    },
+
+    'BigNumber': function (x) {
+      return x.isNaN();
+    },
+
+    'Fraction': function (x) {
+      return false;
+    },
+
+    'Complex': function (x) {
+      return Number.isNaN(x.re) && Number.isNaN(x.im);
+    },
+
+    'Unit': function (x) {
+      return Number.isNaN(x.value);
+    },
+
+    'Array | Matrix': function (x) {
+      return deepMap(x, Number.isNaN);
+    }
+  });
+
+  return isNaN;
+}
+
+exports.name = 'isNaN';
+exports.factory = factory;


Test patch:
diff --git a/test/function/utils/isNaN.test.js b/test/function/utils/isNaN.test.js
new file mode 100644
index 000000000..72cf5724e
--- /dev/null
+++ b/test/function/utils/isNaN.test.js
@@ -0,0 +1,77 @@
+var assert = require('assert');
+var math = require('../../../index');
+var isNaN = math.isNaN;
+var bignumber = math.bignumber;
+var fraction = math.fraction;
+var complex = math.complex;
+var Unit = math.type.Unit;
+var Fraction = math.type.Fraction;
+
+describe('isNegative', function() {
+
+  it('should test whether a number is NaN', function() {
+    assert.strictEqual(isNaN(0), false);
+    assert.strictEqual(isNaN(2), false);
+    assert.strictEqual(isNaN(-3), false);
+    assert.strictEqual(isNaN(Infinity), false);
+    assert.strictEqual(isNaN(-Infinity), false);
+    assert.strictEqual(isNaN(NaN), true);
+  });
+
+  it('should test whether a boolean is NaN', function() {
+    assert.strictEqual(isNaN(true), false);
+    assert.strictEqual(isNaN(false), false);
+  });
+
+  it('should test whether a BigNumber is NaN', function() {
+    assert.strictEqual(isNaN(bignumber(0)), false);
+    assert.strictEqual(isNaN(bignumber(2)), false);
+    assert.strictEqual(isNaN(bignumber(-3)), false);
+    assert.strictEqual(isNaN(bignumber(Infinity)), false);
+    assert.strictEqual(isNaN(bignumber(-Infinity)), false);
+    assert.strictEqual(isNaN(bignumber(NaN)), true);
+  });
+
+  it('should test whether a Fraction is NaN', function() {
+    assert.strictEqual(isNaN(fraction(2)), false);
+    assert.strictEqual(isNaN(fraction(-3)), false);
+    assert.strictEqual(isNaN(fraction(0)), false);
+  });
+
+  it('should test whether a unit is NaN', function() {
+    assert.strictEqual(isNaN(new Unit(0, 'm')), false);
+    assert.strictEqual(isNaN(new Unit(0, 'kB')), false);
+    assert.strictEqual(isNaN(new Unit(5, 'cm')), false);
+    assert.strictEqual(isNaN(new Unit(-3, 'inch')), false);
+    assert.strictEqual(isNaN(new Unit(NaN, 'inch')), true);
+  });
+
+  it('should test whether a complex number contains NaN', function () {
+    assert.strictEqual(isNaN(complex(0, 0)), false);
+    assert.strictEqual(isNaN(complex(NaN, 0)), false);
+    assert.strictEqual(isNaN(complex(0, NaN)), false);
+    assert.strictEqual(isNaN(complex(NaN, NaN)), true);
+  });
+
+  it('should test whether a string contains a NaN', function() {
+    assert.strictEqual(isNaN('2'), false);
+    assert.strictEqual(isNaN('-2'), false);
+    assert.strictEqual(isNaN('0'), false);
+    assert.throws(function () {isNaN('NaN')}, /Error: Cannot convert "NaN" to a number/);
+    assert.strictEqual(isNaN(''), false);
+  });
+
+  it('should test isNegative element wise on an Array', function() {
+    assert.deepEqual(isNaN([0, 5, -2, NaN]), [false, false, false, true]);
+  });
+
+  it('should test isNegative element wise on a Matrix', function() {
+    assert.deepEqual(isNaN(math.matrix([0, 5, -2, NaN])), math.matrix([false, false, false, true]));
+  });
+
+  it('should throw an error in case of unsupported data types', function() {
+    assert.throws(function () {isNaN(new Date())}, /TypeError: Unexpected type of argument/);
+    assert.throws(function () {isNaN({})}, /TypeError: Unexpected type of argument/);
+  });
+
+});