spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← All files
name: src/Formulas/Engineering.ts
-rw-r--r--
11624
  1import {
  2  ArgsChecker
  3} from "../Utilities/ArgsChecker";
  4import {
  5  TypeConverter
  6} from "../Utilities/TypeConverter";
  7import {
  8  ValueError,
  9  NumError
 10} from "../Errors";
 11
 12/**
 13 * Converts a signed binary number to decimal format.
 14 * @param signedBinaryNumber - The signed 10-bit binary value to be converted to decimal, provided as a
 15 * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
 16 * in two's complement format.
 17 * @returns {number}
 18 * @constructor
 19 */
 20let BIN2DEC = function (signedBinaryNumber) : number {
 21  ArgsChecker.checkLength(arguments, 1, "BIN2DEC");
 22  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 23    throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 24  }
 25  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
 26  if (!(/^[01]{1,10}$/).test(n)) {
 27    throw new NumError("Input for BIN2DEC ('" + n + "') is not a valid binary representation.");
 28  }
 29
 30  if (n.length === 10 && n.substring(0, 1) === '1') {
 31    return parseInt(n.substring(1), 2) - 512;
 32  }
 33  return parseInt(n, 2);
 34};
 35
 36
 37/**
 38 * Converts a signed binary number to signed hexadecimal format.
 39 * @param signedBinaryNumber - 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 significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
 43 * @returns {string} string representation of a signed hexadecimal
 44 * @constructor
 45 */
 46let BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
 47  ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2HEX");
 48  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 49    throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 50  }
 51  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
 52  let p = 10;
 53  if (significantDigits !== undefined) {
 54    p = TypeConverter.firstValueAsNumber(significantDigits);
 55  }
 56  if (!(/^[01]{1,10}$/).test(n)) {
 57    throw new NumError("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 NumError("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  let result = parseInt(n.toString(), 2).toString(16).toUpperCase();
 70  if (p === 10) {
 71    return result;
 72  }
 73  let str = "";
 74  for (let i = 0; i < p - result.length; i++) {
 75    str += "0";
 76  }
 77  return str + result;
 78};
 79
 80
 81/**
 82 * Converts a signed binary number to signed octal format.
 83 * @param signedBinaryNumber - The signed 10-bit binary value to be converted to signed octal, provided as a
 84 * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
 85 * in two's complement format.
 86 * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
 87 * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
 88 * total number of digits reaches significant_digits.
 89 * @returns {string} number in octal format
 90 * @constructor
 91 */
 92let BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
 93  ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2OCT");
 94  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 95    throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 96  }
 97  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
 98  let p = 10;
 99  if (significantDigits !== undefined) {
100    p = TypeConverter.firstValueAsNumber(significantDigits);
101  }
102  if (!(/^[01]{1,10}$/).test(n)) {
103    throw new NumError("Input for BIN2OCT ('"+n+"') is not a valid binary representation.");
104  }
105
106  if (n.length === 10 && n.substring(0, 1) === '1') {
107    return (1073741312 + parseInt(n.substring(1), 2)).toString(8);
108  }
109
110  if (p < 1 || p > 10) {
111    throw new NumError("Function BIN2OCT parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
112  }
113  p = Math.floor(p);
114  let result = parseInt(n.toString(), 2).toString(8);
115  if (p === 10) {
116    return result;
117  }
118  if (p >= result.length) {
119    let str = "";
120    for (let i = 0; i < p - result.length - 1; i++) {
121      str += "0";
122    }
123    return str + result;
124  }
125};
126
127/**
128 * Converts a decimal number to signed octal format.
129 * @param decimalDumber - The decimal value to be converted to signed octal,provided as a string. For this
130 * function, this value has a maximum of 536870911 if positive, and a minimum of -53687092 if negative.
131 * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
132 * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
133 * number of digits reaches significant_digits.
134 * @returns {string} octal string representation of the decimal number
135 * @constructor
136 */
137let DEC2OCT = function (decimalDumber, significantDigits?) : string {
138  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2OCT");
139  let n = TypeConverter.firstValueAsNumber(decimalDumber);
140  if (n < 0) {
141    n = Math.ceil(n);
142  }
143  if (n > 0) {
144    n = Math.floor(n);
145  }
146  let p = 10;
147  let placesPresent = false;
148  if (significantDigits !== undefined) {
149    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
150    placesPresent = true;
151  }
152  if (n < -53687092 || n > 536870911) {
153    throw new NumError("Function DEC2OCT parameter 1 value is " + n + ". Valid values are between -53687092 and 536870911 inclusive.");
154  }
155  if (p < 1 || p > 10) {
156    throw new NumError("Function DEC2OCT parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
157  }
158  if (n < 0) {
159    return (1073741824 + n).toString(8).toUpperCase();
160  }
161
162  // Convert decimal number to hexadecimal
163  let result = parseInt(n.toString(), 10).toString(8).toUpperCase();
164  if (!placesPresent) {
165    return result;
166  }
167  let str = "";
168  for (let i = 0; i < p - result.length; i++) {
169    str += "0";
170  }
171  return str + result.toUpperCase();
172};
173
174
175/**
176 * Converts a decimal number to signed hexadecimal format.
177 * @param decimalDumber - The decimal value to be converted to signed hexadecimal, provided as a string. This
178 * value has a maximum of 549755813887 if positive, and a minimum of -549755814888 if negative.
179 * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
180 * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
181 * total number of digits reaches significant_digits. This value is ignored if decimal_number is negative.
182 * @returns {string} hexadecimal string representation of the decimal number
183 * @constructor
184 */
185let DEC2HEX = function (decimalDumber, significantDigits?) : string {
186  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2HEX");
187  let n = TypeConverter.firstValueAsNumber(decimalDumber);
188  if (n < 0) {
189    n = Math.ceil(n);
190  }
191  if (n > 0) {
192    n = Math.floor(n);
193  }
194  let p = 10;
195  let placesPresent = false;
196  if (significantDigits !== undefined) {
197    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
198    placesPresent = true;
199  }
200  if (n < -549755813888 || n > 549755813887) {
201    throw new NumError("Function DEC2HEX parameter 1 value is " + n + ". Valid values are between -549755813888 and 549755813887 inclusive.");
202  }
203  if (p < 1 || p > 10) {
204    throw new NumError("Function DEC2HEX parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
205  }
206  // Ignore places and return a 10-character hexadecimal number if number is negative
207  if (n < 0) {
208    return (1099511627776 + n).toString(16).toUpperCase();
209  }
210
211  // Convert decimal number to hexadecimal
212  let result = parseInt(n.toString(), 10).toString(16).toUpperCase();
213  if (!placesPresent) {
214    return result;
215  }
216  let str = "";
217  for (let i = 0; i < p - result.length; i++) {
218    str += "0";
219  }
220  return str + result;
221};
222
223/**
224 * Converts a decimal number to signed binary format.
225 * @param decimalDumber - The decimal value to be converted to signed binary, provided as a string. For this
226 * function, this value has a maximum of 511 if positive, and a minimum of -512 if negative.
227 * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
228 * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
229 * number of digits reaches significant_digits.
230 * @returns {string} signed binary string representation of the input decimal number.
231 * @constructor
232 */
233let DEC2BIN = function (decimalDumber, significantDigits?) : string {
234  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2BIN");
235  let n = TypeConverter.firstValueAsNumber(decimalDumber);
236  if (n < 0) {
237    n = Math.ceil(n);
238  }
239  if (n > 0) {
240    n = Math.floor(n);
241  }
242  if (n === 0 || n === 1) {
243    return n.toString();
244  }
245  let p = 10;
246  let placesPresent = false;
247  if (significantDigits !== undefined) {
248    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
249    placesPresent = true;
250  }
251
252  if (n < -512 || n > 511) {
253    throw new NumError("Function DEC2BIN parameter 1 value is " + n + ". Valid values are between -512 and 511 inclusive.");
254  }
255  if (p < 1 || p > 10) {
256    throw new NumError("Function DEC2BIN parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
257  }
258
259  // Ignore places and return a 10-character binary number if number is negative
260  if (n < 0) {
261    let count = (9 - (512 + n).toString(2).length);
262    let st = "";
263    for (let i = 0; i < count; i++) {
264      st += "0";
265    }
266    return "1" + st + (512 + n).toString(2);
267  }
268
269  // Convert decimal number to binary
270  let result = parseInt(n.toString(), 10).toString(2);
271
272  // Pad return value with leading 0s (zeros) if necessary
273  if (p >= result.length) {
274    let str = "";
275    for (let i = 0; i < (p - result.length); i++) {
276      str += "0";
277    }
278    let workingString = str + result;
279    if (!placesPresent) {
280      let returnString = "";
281      for (let i = 0; i < workingString.length; i++) {
282        let char = workingString[i];
283        if (char === "1") {
284          break;
285        }
286        returnString = workingString.slice(i+1);
287      }
288      return returnString;
289    }
290    return workingString;
291  }
292};
293
294/**
295 * Compare two numeric values, returning 1 if they're equal.
296 * @param one - The first number to compare.
297 * @param two - The second number to compare.
298 * @returns {number} 1 if they're equal, 0 if they're not equal.
299 * @constructor
300 */
301let DELTA = function (one, two?) : number {
302  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DELTA");
303  if (two === undefined) {
304    return TypeConverter.valueToNumber(one) === 0 ? 1 : 0;
305  }
306  return TypeConverter.valueToNumber(one) === TypeConverter.valueToNumber(two) ? 1 : 0;
307};
308
309export {
310  BIN2DEC,
311  BIN2HEX,
312  BIN2OCT,
313  DEC2BIN,
314  DEC2HEX,
315  DEC2OCT,
316  DELTA
317}