commit
message
Added Formulas.BIN2HEX
author
Ben Vogt <[email protected]>
date
2017-02-18 05:37:44
stats
4 file(s) changed,
107 insertions(+),
25 deletions(-)
files
src/RawFormulas/RawFormulas.ts
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
tests/SheetFormulaTest.ts
1diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
2index de62157..6da8d24 100644
3--- a/src/RawFormulas/RawFormulas.ts
4+++ b/src/RawFormulas/RawFormulas.ts
5@@ -83,7 +83,6 @@ import * as ERRORS from "../Errors"
6 import {Cell} from "../Cell";
7
8 var ACCRINT = Formula["ACCRINT"];
9-var BIN2HEX = Formula["BIN2HEX"];
10 var BIN2OCT = Formula["BIN2OCT"];
11 var DECIMAL = Formula["DECIMAL"];
12 var COMBIN = Formula["COMBIN"];
13@@ -140,8 +139,11 @@ var YEARFRAC = Formula["YEARFRAC"];
14 * @returns {number}
15 * @constructor
16 */
17-var BIN2DEC = function (...values) {
18+var BIN2DEC = function (...values) : number {
19 ArgsChecker.checkLength(values, 1);
20+ if (typeof TypeCaster.firstValue(values[0]) === "boolean") {
21+ throw new CellError(ERRORS.VALUE_ERROR, "Function BIN2DEC parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
22+ }
23 var n = TypeCaster.firstValueAsString(values[0]);
24 if (!(/^[01]{1,10}$/).test(n)) {
25 throw new CellError(ERRORS.NUM_ERROR, "Input for BIN2DEC ('"+n+"') is not a valid binary representation.");
26@@ -149,12 +151,56 @@ var BIN2DEC = function (...values) {
27
28 if (n.length === 10 && n.substring(0, 1) === '1') {
29 return parseInt(n.substring(1), 2) - 512;
30- } else {
31- return parseInt(n, 2);
32 }
33+ return parseInt(n, 2);
34+};
35+
36+
37+/**
38+ * Converts a signed binary number to signed hexadecimal format.
39+ * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to signed hexadecimal,
40+ * provided as a string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are
41+ * represented in two's complement format.
42+ * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
43+ * @returns {string} string representation of a signed hexadecimal
44+ * @constructor
45+ */
46+var BIN2HEX = function (...values) : string {
47+ ArgsChecker.checkLengthWithin(values, 1, 2);
48+ if (typeof TypeCaster.firstValue(values[0]) === "boolean") {
49+ throw new CellError(ERRORS.VALUE_ERROR, "Function BIN2HEX parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
50+ }
51+ var n = TypeCaster.firstValueAsString(values[0]);
52+ var p = 10;
53+ if (values.length === 2) {
54+ p = TypeCaster.firstValueAsNumber(values[1]);
55+ }
56+ if (!(/^[01]{1,10}$/).test(n)) {
57+ throw new CellError(ERRORS.NUM_ERROR, "Input for BIN2HEX ('"+n+"') is not a valid binary representation.");
58+ }
59+
60+ if (n.length === 10 && n.substring(0, 1) === '1') {
61+ return (1099511627264 + parseInt(n.substring(1), 2)).toString(16).toUpperCase();
62+ }
63+
64+ if (p < 1 || p > 10) {
65+ throw new CellError(ERRORS.NUM_ERROR, "Function BIN2HEX parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
66+ }
67+ p = Math.floor(p);
68+ // Convert decimal number to hexadecimal
69+ var result = parseInt(n.toString(), 2).toString(16).toUpperCase();
70+ if (p === 10) {
71+ return result;
72+ }
73+ var str = "";
74+ for (var i = 0; i < p - result.length; i++) {
75+ str += "0";
76+ }
77+ return str + result;
78 };
79
80
81+
82 /**
83 * Converts an angle value in degrees to radians.
84 * @param values[0] angle - The angle to convert from degrees to radians.
85@@ -219,16 +265,12 @@ var DEC2OCT = function (...values) : string {
86 var result = parseInt(n.toString(), 10).toString(8).toUpperCase();
87 if (!placesPresent) {
88 return result;
89- } else {
90- if (p >= result.length) {
91- // Throw NUM error?
92- }
93- var str = "";
94- for (var i = 0; i < p - result.length; i++) {
95- str += "0";
96- }
97- return str + result.toUpperCase();
98 }
99+ var str = "";
100+ for (var i = 0; i < p - result.length; i++) {
101+ str += "0";
102+ }
103+ return str + result.toUpperCase();
104 };
105
106
107@@ -272,16 +314,12 @@ var DEC2HEX = function (...values) : string {
108 var result = parseInt(n.toString(), 10).toString(16).toUpperCase();
109 if (!placesPresent) {
110 return result;
111- } else {
112- if (p >= result.length) {
113- // Throw NUM error?
114- }
115- var str = "";
116- for (var i = 0; i < p - result.length; i++) {
117- str += "0";
118- }
119- return str + result.toUpperCase();
120 }
121+ var str = "";
122+ for (var i = 0; i < p - result.length; i++) {
123+ str += "0";
124+ }
125+ return str + result;
126 };
127
128 /**
129diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
130index 7042ea5..447d62a 100644
131--- a/src/RawFormulas/Utils.ts
132+++ b/src/RawFormulas/Utils.ts
133@@ -197,6 +197,16 @@ class TypeCaster {
134 return TypeCaster.valueToString(input);
135 }
136
137+ static firstValue(input: any) : any {
138+ if (input instanceof Array) {
139+ if (input.length === 0) {
140+ throw new CellError(ERRORS.REF_ERROR, "Reference does not exist.");
141+ }
142+ return TypeCaster.firstValue(input[0]);
143+ }
144+ return input;
145+ }
146+
147 /**
148 * Takes any input type and will throw a REF_ERROR or coerce it into a string.
149 * @param input to attempt to coerce into a string
150diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
151index 7305733..bcfaca4 100644
152--- a/tests/FormulasTest.ts
153+++ b/tests/FormulasTest.ts
154@@ -289,6 +289,9 @@ catchAndAssertEquals(function() {
155 assertEquals(BIN2DEC("1010101010"), -342);
156 assertEquals(BIN2DEC("10"), 2);
157 assertEquals(BIN2DEC(["10", "str"]), 2);
158+catchAndAssertEquals(function() {
159+ BIN2DEC(false);
160+}, ERRORS.VALUE_ERROR);
161 catchAndAssertEquals(function() {
162 BIN2DEC("str");
163 }, ERRORS.NUM_ERROR);
164@@ -300,7 +303,31 @@ catchAndAssertEquals(function() {
165 }, ERRORS.NA_ERROR);
166
167
168-assertEquals(BIN2HEX(1010101010), "fffffffeaa");
169+// Test BIN2HEX
170+assertEquals(BIN2HEX("1010101010"), "FFFFFFFEAA");
171+assertEquals(BIN2HEX("10"), "2");
172+assertEquals(BIN2HEX("10101010"), "AA");
173+assertEquals(BIN2HEX("10101010", 4), "00AA");
174+assertEquals(BIN2HEX(["10101010"], [4]), "00AA");
175+catchAndAssertEquals(function() {
176+ BIN2HEX("10101010", 22);
177+}, ERRORS.NUM_ERROR);
178+catchAndAssertEquals(function() {
179+ BIN2HEX(false);
180+}, ERRORS.VALUE_ERROR);
181+catchAndAssertEquals(function() {
182+ BIN2HEX("10101010", 0);
183+}, ERRORS.NUM_ERROR);
184+catchAndAssertEquals(function() {
185+ BIN2DEC("str");
186+}, ERRORS.NUM_ERROR);
187+catchAndAssertEquals(function() {
188+ BIN2DEC();
189+}, ERRORS.NA_ERROR);
190+catchAndAssertEquals(function() {
191+ BIN2DEC("10", 4, 4);
192+}, ERRORS.NA_ERROR);
193+
194
195 assertEquals(BIN2OCT(1010101010), "7777777252");
196
197diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
198index 35d4d5c..ded4855 100644
199--- a/tests/SheetFormulaTest.ts
200+++ b/tests/SheetFormulaTest.ts
201@@ -88,7 +88,7 @@ testFormula("=BIN2DEC('1010101010')", -342);
202 // testFormula('=BINOMINV(6, 0.5, 0.75)', 4);
203
204 // Test BIN2HEX
205-testFormula("=BIN2HEX(1010101010)", "fffffffeaa");
206+testFormula("=BIN2HEX(1010101010)", "FFFFFFFEAA");
207
208 // Test BIN2OCT
209 testFormula("=BIN2OCT(1010101010)", "7777777252");