spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[ALL] checking for DIV_ZERO errors
author
Ben Vogt <[email protected]>
date
2017-04-02 19:32:38
stats
5 file(s) changed, 41 insertions(+), 21 deletions(-)
files
README.md
src/RawFormulas/Financial.ts
src/RawFormulas/RawFormulas.ts
src/RawFormulas/Statistical.ts
src/RawFormulas/Utils.ts
  1diff --git a/README.md b/README.md
  2index f3512bf..8d52f4a 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -34,10 +34,6 @@ Group by error type and have some useful functions that will call with 0, N, N+1
  6 checker. Also, test for *all possible* errors that could be thrown, and *all possible types* that could be passed in.
  7 Another thing to think about would be throwing custom errors if an object is passed in.
  8 
  9-### DIV_ZERO Error
 10-This error is thrown every time we're about to divide by zero in a formula. There are definitely a couple formulas that
 11-don't check for this, and they should.
 12-
 13 ### jStat functions should know their caller
 14 Either through `arguments`, or directly passed in like `mean("FORMULA", [10, 20, 30])`
 15 
 16diff --git a/src/RawFormulas/Financial.ts b/src/RawFormulas/Financial.ts
 17index e9131f8..7dae7f2 100644
 18--- a/src/RawFormulas/Financial.ts
 19+++ b/src/RawFormulas/Financial.ts
 20@@ -1,6 +1,7 @@
 21 import {
 22   ArgsChecker,
 23-  TypeCaster
 24+  TypeCaster,
 25+  checkForDevideByZero
 26 } from "./Utils";
 27 import {
 28   CellError
 29@@ -52,7 +53,7 @@ var DDB = function (...values) : number {
 30   var total = 0;
 31   var current = 0;
 32   for (var i = 1; i <= period; i++) {
 33-    current = Math.min((cost - total) * (factor / life), (cost - salvage - total));
 34+    current = Math.min((cost - total) * (factor / checkForDevideByZero(life)), (cost - salvage - total));
 35     total += current;
 36   }
 37   return current;
 38@@ -103,6 +104,9 @@ var DB = function (...values) : number {
 39   if (salvage >= cost) {
 40     return 0;
 41   }
 42+  if (cost === 0 && salvage !== 0) {
 43+    throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function DB cause a divide by zero error.")
 44+  }
 45   var rate = (1 - Math.pow(salvage / cost, 1 / life));
 46   var initial = cost * rate * month / 12;
 47   var total = initial;
 48@@ -142,7 +146,12 @@ var DOLLAR = function (...values) : number {
 49   var v = TypeCaster.firstValueAsNumber(values[0]);
 50   var places = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 2;
 51   var sign = (v > 0) ? 1 : -1;
 52-  return sign * (Math.floor(Math.abs(v) * Math.pow(10, places))) / Math.pow(10, places);
 53+  var divisor = sign * (Math.floor(Math.abs(v) * Math.pow(10, places)));
 54+  var pow = Math.pow(10, places);
 55+  if (pow === 0 && divisor !== 0) {
 56+    throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function DOLLAR cause a divide by zero error.")
 57+  }
 58+  return divisor / pow;
 59 };
 60 
 61 
 62diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
 63index 0aaa2a1..962f2cf 100644
 64--- a/src/RawFormulas/RawFormulas.ts
 65+++ b/src/RawFormulas/RawFormulas.ts
 66@@ -119,18 +119,6 @@ import {
 67   YEARFRAC
 68 } from "./Date"
 69 
 70-import {
 71-  CriteriaFunctionFactory,
 72-  ArgsChecker,
 73-  Filter,
 74-  TypeCaster,
 75-  Serializer
 76-} from "./Utils";
 77-import {
 78-  CellError
 79-} from "../Errors"
 80-import * as ERRORS from "../Errors"
 81-
 82 var ACCRINT = Formula["ACCRINT"];
 83 var CONVERT = Formula["CONVERT"];
 84 
 85diff --git a/src/RawFormulas/Statistical.ts b/src/RawFormulas/Statistical.ts
 86index adb7f9e..742244f 100644
 87--- a/src/RawFormulas/Statistical.ts
 88+++ b/src/RawFormulas/Statistical.ts
 89@@ -144,6 +144,9 @@ var AVEDEV = function (...values) {
 90     result = result + TypeCaster.valueToNumber(flatValues[i]);
 91     count++;
 92   }
 93+  if (count === 0) {
 94+    throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function AVEDEV caused a devide by zero error.");
 95+  }
 96   var mean = result / count;
 97 
 98   for (var i = 0; i < flatValues.length; i++) {
 99@@ -175,6 +178,9 @@ var AVERAGEA = function (...values) {
100       count++;
101     }
102   }
103+  if (count === 0) {
104+    throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function AVEDEV caused a devide by zero error.");
105+  }
106   return result / count;
107 };
108 
109@@ -205,6 +211,9 @@ var CORREL = function (...values) : number {
110     return sum;
111   }
112   function mean(arr) {
113+    if (arr.length === 0) {
114+      throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function CORREL caused a divide by zero error.");
115+    }
116     return sum(arr) / arr.length;
117   }
118   function sumsqerr(arr) {
119@@ -248,7 +257,7 @@ var CORREL = function (...values) : number {
120   if (stdevArr1 === 0 || stdevArr2 === 0) {
121     throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function CORREL caused a divide by zero error.");
122   }
123-  return covariance(arr1, arr2) / stdev(arr1, 1) / stdev(arr2, 1);
124+  return covariance(arr1, arr2) / stdevArr1 / stdevArr2;
125 };
126 
127 /**
128diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
129index 4e4dd5a..18f8037 100644
130--- a/src/RawFormulas/Utils.ts
131+++ b/src/RawFormulas/Utils.ts
132@@ -897,6 +897,22 @@ class Serializer {
133   }
134 }
135 
136+/**
137+ * Catches divide by zero situations and throws them as errors
138+ * @param n number to check
139+ * @returns {number} n as long as it's not zero.
140+ */
141+var checkForDevideByZero = function(n : number) : number {
142+  n = +n;  // Coerce to number.
143+  if (!n) {  // Matches +0, -0, NaN
144+    throw new CellError(ERRORS.DIV_ZERO_ERROR, "Evaluation of function caused a divide by zero error.");
145+  }
146+  return n;
147+};
148+
149+var divideAndCheck
150+
151+
152 
153 export {
154   ArgsChecker,
155@@ -904,5 +920,6 @@ export {
156   DateRegExBuilder,
157   Filter,
158   Serializer,
159-  TypeCaster
160+  TypeCaster,
161+  checkForDevideByZero
162 }
163\ No newline at end of file