Merge branch 'artemisbot-features/big-number'

This commit is contained in:
n1474335 2018-01-05 18:50:13 +00:00
commit ab7c05284d
9 changed files with 148 additions and 115 deletions

5
package-lock.json generated
View File

@ -1053,6 +1053,11 @@
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
"dev": true "dev": true
}, },
"bignumber.js": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-5.0.0.tgz",
"integrity": "sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg=="
},
"binary-extensions": { "binary-extensions": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",

View File

@ -68,6 +68,7 @@
}, },
"dependencies": { "dependencies": {
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"bignumber.js": "^5.0.0",
"bootstrap": "^3.3.7", "bootstrap": "^3.3.7",
"bootstrap-colorpicker": "^2.5.2", "bootstrap-colorpicker": "^2.5.2",
"bootstrap-switch": "^3.3.4", "bootstrap-switch": "^3.3.4",

View File

@ -1,14 +1,16 @@
import Utils from "./Utils.js"; import Utils from "./Utils.js";
import BigNumber from "bignumber.js";
/** /**
* The data being operated on by each operation. * The data being operated on by each operation.
* *
* @author n1474335 [n1474335@gmail.com] * @author n1474335 [n1474335@gmail.com]
* @author Matt C [matt@artemisbot.uk]
* @copyright Crown Copyright 2016 * @copyright Crown Copyright 2016
* @license Apache-2.0 * @license Apache-2.0
* *
* @class * @class
* @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {byteArray|string|number|ArrayBuffer|BigNumber} value - The value of the input data.
* @param {number} type - The data type of value, see Dish enums. * @param {number} type - The data type of value, see Dish enums.
*/ */
const Dish = function(value, type) { const Dish = function(value, type) {
@ -47,6 +49,12 @@ Dish.HTML = 3;
* @enum * @enum
*/ */
Dish.ARRAY_BUFFER = 4; Dish.ARRAY_BUFFER = 4;
/**
* Dish data type enum for BigNumbers.
* @readonly
* @enum
*/
Dish.BIG_NUMBER = 5;
/** /**
@ -57,22 +65,22 @@ Dish.ARRAY_BUFFER = 4;
* @returns {number} The data type enum value. * @returns {number} The data type enum value.
*/ */
Dish.typeEnum = function(typeStr) { Dish.typeEnum = function(typeStr) {
switch (typeStr) { switch (typeStr.toLowerCase()) {
case "byteArray": case "bytearray":
case "Byte array": case "byte array":
return Dish.BYTE_ARRAY; return Dish.BYTE_ARRAY;
case "string": case "string":
case "String":
return Dish.STRING; return Dish.STRING;
case "number": case "number":
case "Number":
return Dish.NUMBER; return Dish.NUMBER;
case "html": case "html":
case "HTML":
return Dish.HTML; return Dish.HTML;
case "arrayBuffer": case "arraybuffer":
case "ArrayBuffer": case "array buffer":
return Dish.ARRAY_BUFFER; return Dish.ARRAY_BUFFER;
case "bignumber":
case "big number":
return Dish.BIG_NUMBER;
default: default:
throw "Invalid data type string. No matching enum."; throw "Invalid data type string. No matching enum.";
} }
@ -83,8 +91,8 @@ Dish.typeEnum = function(typeStr) {
* Returns the data type string for the given type enum. * Returns the data type string for the given type enum.
* *
* @static * @static
* @param {string} typeEnum - The enum value of the data type. * @param {number} typeEnum - The enum value of the data type.
* @returns {number} The data type as a string. * @returns {string} The data type as a string.
*/ */
Dish.enumLookup = function(typeEnum) { Dish.enumLookup = function(typeEnum) {
switch (typeEnum) { switch (typeEnum) {
@ -98,6 +106,8 @@ Dish.enumLookup = function(typeEnum) {
return "html"; return "html";
case Dish.ARRAY_BUFFER: case Dish.ARRAY_BUFFER:
return "ArrayBuffer"; return "ArrayBuffer";
case Dish.BIG_NUMBER:
return "BigNumber";
default: default:
throw "Invalid data type enum. No matching type."; throw "Invalid data type enum. No matching type.";
} }
@ -107,7 +117,7 @@ Dish.enumLookup = function(typeEnum) {
/** /**
* Sets the data value and type and then validates them. * Sets the data value and type and then validates them.
* *
* @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {byteArray|string|number|ArrayBuffer|BigNumber} value - The value of the input data.
* @param {number} type - The data type of value, see Dish enums. * @param {number} type - The data type of value, see Dish enums.
*/ */
Dish.prototype.set = function(value, type) { Dish.prototype.set = function(value, type) {
@ -126,7 +136,7 @@ Dish.prototype.set = function(value, type) {
* Returns the value of the data in the type format specified. * Returns the value of the data in the type format specified.
* *
* @param {number} type - The data type of value, see Dish enums. * @param {number} type - The data type of value, see Dish enums.
* @returns {byteArray|string|number|ArrayBuffer} The value of the output data. * @returns {byteArray|string|number|ArrayBuffer|BigNumber} The value of the output data.
*/ */
Dish.prototype.get = function(type) { Dish.prototype.get = function(type) {
if (this.type !== type) { if (this.type !== type) {
@ -159,6 +169,9 @@ Dish.prototype.translate = function(toType) {
// Array.from() would be nicer here, but it's slightly slower // Array.from() would be nicer here, but it's slightly slower
this.value = Array.prototype.slice.call(new Uint8Array(this.value)); this.value = Array.prototype.slice.call(new Uint8Array(this.value));
break; break;
case Dish.BIG_NUMBER:
this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toString()) : [];
break;
default: default:
break; break;
} }
@ -180,6 +193,14 @@ Dish.prototype.translate = function(toType) {
this.value = new Uint8Array(this.value).buffer; this.value = new Uint8Array(this.value).buffer;
this.type = Dish.ARRAY_BUFFER; this.type = Dish.ARRAY_BUFFER;
break; break;
case Dish.BIG_NUMBER:
try {
this.value = new BigNumber(Utils.byteArrayToUtf8(this.value));
} catch (err) {
this.value = new BigNumber(NaN);
}
this.type = Dish.BIG_NUMBER;
break;
default: default:
break; break;
} }
@ -215,6 +236,8 @@ Dish.prototype.valid = function() {
return typeof this.value === "number"; return typeof this.value === "number";
case Dish.ARRAY_BUFFER: case Dish.ARRAY_BUFFER:
return this.value instanceof ArrayBuffer; return this.value instanceof ArrayBuffer;
case Dish.BIG_NUMBER:
return this.value instanceof BigNumber;
default: default:
return false; return false;
} }
@ -235,6 +258,7 @@ Dish.prototype.size = function() {
case Dish.HTML: case Dish.HTML:
return this.value.length; return this.value.length;
case Dish.NUMBER: case Dish.NUMBER:
case Dish.BIG_NUMBER:
return this.value.toString().length; return this.value.toString().length;
case Dish.ARRAY_BUFFER: case Dish.ARRAY_BUFFER:
return this.value.byteLength; return this.value.byteLength;

View File

@ -524,7 +524,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>18.5</code>", description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>18.5</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -537,7 +537,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>1.5</code>", description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>1.5</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -550,7 +550,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>40</code>", description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>40</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -563,7 +563,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>2.5</code>", description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>2.5</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -576,7 +576,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5 .5</code> becomes <code>4.75</code>", description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5 .5</code> becomes <code>4.75</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -589,7 +589,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 1 .5</code> becomes <code>4.5</code>", description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 1 .5</code> becomes <code>4.5</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -602,7 +602,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>4.089281382128433</code>", description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>4.089281382128433</code>",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Delimiter", name: "Delimiter",
@ -806,7 +806,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Converts a number to decimal from a given numerical base.", description: "Converts a number to decimal from a given numerical base.",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Radix", name: "Radix",
@ -818,7 +818,7 @@ const OperationConfig = {
"To Base": { "To Base": {
module: "Default", module: "Default",
description: "Converts a decimal number to a given numerical base.", description: "Converts a decimal number to a given numerical base.",
inputType: "number", inputType: "BigNumber",
outputType: "string", outputType: "string",
args: [ args: [
{ {
@ -2515,8 +2515,8 @@ const OperationConfig = {
"Convert distance": { "Convert distance": {
module: "Default", module: "Default",
description: "Converts a unit of distance to another format.", description: "Converts a unit of distance to another format.",
inputType: "number", inputType: "BigNumber",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Input units", name: "Input units",
@ -2533,8 +2533,8 @@ const OperationConfig = {
"Convert area": { "Convert area": {
module: "Default", module: "Default",
description: "Converts a unit of area to another format.", description: "Converts a unit of area to another format.",
inputType: "number", inputType: "BigNumber",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Input units", name: "Input units",
@ -2551,8 +2551,8 @@ const OperationConfig = {
"Convert mass": { "Convert mass": {
module: "Default", module: "Default",
description: "Converts a unit of mass to another format.", description: "Converts a unit of mass to another format.",
inputType: "number", inputType: "BigNumber",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Input units", name: "Input units",
@ -2569,8 +2569,8 @@ const OperationConfig = {
"Convert speed": { "Convert speed": {
module: "Default", module: "Default",
description: "Converts a unit of speed to another format.", description: "Converts a unit of speed to another format.",
inputType: "number", inputType: "BigNumber",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Input units", name: "Input units",
@ -2587,8 +2587,8 @@ const OperationConfig = {
"Convert data units": { "Convert data units": {
module: "Default", module: "Default",
description: "Converts a unit of data to another format.", description: "Converts a unit of data to another format.",
inputType: "number", inputType: "BigNumber",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Input units", name: "Input units",
@ -3750,7 +3750,7 @@ const OperationConfig = {
module: "Default", module: "Default",
description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.", description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.",
inputType: "string", inputType: "string",
outputType: "number", outputType: "BigNumber",
args: [ args: [
{ {
name: "Scheme", name: "Scheme",
@ -3778,7 +3778,7 @@ const OperationConfig = {
"To BCD": { "To BCD": {
module: "Default", module: "Default",
description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign", description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign",
inputType: "number", inputType: "BigNumber",
outputType: "string", outputType: "string",
args: [ args: [
{ {

View File

@ -1,4 +1,5 @@
import Utils from "../Utils.js"; import Utils from "../Utils.js";
import BigNumber from "bignumber.js";
/** /**
@ -24,11 +25,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runSum: function(input, args) { runSum: function(input, args) {
const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -37,11 +38,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runSub: function(input, args) { runSub: function(input, args) {
let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -50,11 +51,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runMulti: function(input, args) { runMulti: function(input, args) {
let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -63,11 +64,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runDiv: function(input, args) { runDiv: function(input, args) {
let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -76,11 +77,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runMean: function(input, args) { runMean: function(input, args) {
let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -89,11 +90,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runMedian: function(input, args) { runMedian: function(input, args) {
let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -102,11 +103,11 @@ const Arithmetic = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runStdDev: function(input, args) { runStdDev: function(input, args) {
let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0]));
return typeof(val) === "number" ? val : NaN; return val instanceof BigNumber ? val : new BigNumber(NaN);
}, },
@ -116,7 +117,7 @@ const Arithmetic = {
* @private * @private
* @param {string[]} input * @param {string[]} input
* @param {string} delim * @param {string} delim
* @returns {number[]} * @returns {BigNumber[]}
*/ */
_createNumArray: function(input, delim) { _createNumArray: function(input, delim) {
delim = Utils.charRep[delim || "Space"]; delim = Utils.charRep[delim || "Space"];
@ -125,14 +126,14 @@ const Arithmetic = {
num; num;
for (let i = 0; i < splitNumbers.length; i++) { for (let i = 0; i < splitNumbers.length; i++) {
if (splitNumbers[i].indexOf(".") >= 0) { try {
num = parseFloat(splitNumbers[i].trim()); num = BigNumber(splitNumbers[i].trim());
} else { if (!num.isNaN()) {
num = parseInt(splitNumbers[i].trim(), 0);
}
if (!isNaN(num)) {
numbers.push(num); numbers.push(num);
} }
} catch (err) {
// This line is not a valid number
}
} }
return numbers; return numbers;
}, },
@ -142,12 +143,12 @@ const Arithmetic = {
* Adds an array of numbers and returns the value. * Adds an array of numbers and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_sum: function(data) { _sum: function(data) {
if (data.length > 0) { if (data.length > 0) {
return data.reduce((acc, curr) => acc + curr); return data.reduce((acc, curr) => acc.plus(curr));
} }
}, },
@ -156,12 +157,12 @@ const Arithmetic = {
* Subtracts an array of numbers and returns the value. * Subtracts an array of numbers and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_sub: function(data) { _sub: function(data) {
if (data.length > 0) { if (data.length > 0) {
return data.reduce((acc, curr) => acc - curr); return data.reduce((acc, curr) => acc.minus(curr));
} }
}, },
@ -170,12 +171,12 @@ const Arithmetic = {
* Multiplies an array of numbers and returns the value. * Multiplies an array of numbers and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_multi: function(data) { _multi: function(data) {
if (data.length > 0) { if (data.length > 0) {
return data.reduce((acc, curr) => acc * curr); return data.reduce((acc, curr) => acc.times(curr));
} }
}, },
@ -184,12 +185,12 @@ const Arithmetic = {
* Divides an array of numbers and returns the value. * Divides an array of numbers and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_div: function(data) { _div: function(data) {
if (data.length > 0) { if (data.length > 0) {
return data.reduce((acc, curr) => acc / curr); return data.reduce((acc, curr) => acc.div(curr));
} }
}, },
@ -198,12 +199,12 @@ const Arithmetic = {
* Computes mean of a number array and returns the value. * Computes mean of a number array and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_mean: function(data) { _mean: function(data) {
if (data.length > 0) { if (data.length > 0) {
return Arithmetic._sum(data) / data.length; return Arithmetic._sum(data).div(data.length);
} }
}, },
@ -212,14 +213,14 @@ const Arithmetic = {
* Computes median of a number array and returns the value. * Computes median of a number array and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_median: function (data) { _median: function (data) {
if ((data.length % 2) === 0) { if ((data.length % 2) === 0 && data.length > 0) {
let first, second; let first, second;
data.sort(function(a, b){ data.sort(function(a, b){
return a - b; return a.minus(b);
}); });
first = data[Math.floor(data.length / 2)]; first = data[Math.floor(data.length / 2)];
second = data[Math.floor(data.length / 2) - 1]; second = data[Math.floor(data.length / 2) - 1];
@ -234,17 +235,17 @@ const Arithmetic = {
* Computes standard deviation of a number array and returns the value. * Computes standard deviation of a number array and returns the value.
* *
* @private * @private
* @param {number[]} data * @param {BigNumber[]} data
* @returns {number} * @returns {BigNumber}
*/ */
_stdDev: function (data) { _stdDev: function (data) {
if (data.length > 0) { if (data.length > 0) {
let avg = Arithmetic._mean(data); let avg = Arithmetic._mean(data);
let devSum = 0; let devSum = new BigNumber(0);
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
devSum += (data[i] - avg) ** 2; devSum = devSum.plus(data[i].minus(avg).pow(2));
} }
return Math.sqrt(devSum / data.length); return devSum.div(data.length).sqrt();
} }
}, },
}; };

View File

@ -1,4 +1,5 @@
import Utils from "../Utils.js"; import Utils from "../Utils.js";
import BigNumber from "bignumber.js";
/** /**
@ -61,14 +62,14 @@ const BCD = {
/** /**
* To BCD operation. * To BCD operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*/ */
runToBCD: function(input, args) { runToBCD: function(input, args) {
if (isNaN(input)) if (input.isNaN())
return "Invalid input"; return "Invalid input";
if (Math.floor(input) !== input) if (!input.floor().equals(input))
return "Fractional values are not supported by BCD"; return "Fractional values are not supported by BCD";
const encoding = BCD.ENCODING_LOOKUP[args[0]], const encoding = BCD.ENCODING_LOOKUP[args[0]],
@ -77,7 +78,7 @@ const BCD = {
outputFormat = args[3]; outputFormat = args[3];
// Split input number up into separate digits // Split input number up into separate digits
const digits = input.toString().split(""); const digits = input.toFixed().split("");
if (digits[0] === "-" || digits[0] === "+") { if (digits[0] === "-" || digits[0] === "+") {
digits.shift(); digits.shift();
@ -152,7 +153,7 @@ const BCD = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runFromBCD: function(input, args) { runFromBCD: function(input, args) {
const encoding = BCD.ENCODING_LOOKUP[args[0]], const encoding = BCD.ENCODING_LOOKUP[args[0]],
@ -206,7 +207,7 @@ const BCD = {
output += val.toString(); output += val.toString();
}); });
return parseInt(output, 10); return new BigNumber(output);
}, },
}; };

View File

@ -1,3 +1,5 @@
import BigNumber from "bignumber.js";
/** /**
* Numerical base operations. * Numerical base operations.
* *
@ -18,7 +20,7 @@ const Base = {
/** /**
* To Base operation. * To Base operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*/ */
@ -39,7 +41,7 @@ const Base = {
* *
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runFrom: function(input, args) { runFrom: function(input, args) {
const radix = args[0] || Base.DEFAULT_RADIX; const radix = args[0] || Base.DEFAULT_RADIX;
@ -48,14 +50,14 @@ const Base = {
} }
let number = input.replace(/\s/g, "").split("."), let number = input.replace(/\s/g, "").split("."),
result = parseInt(number[0], radix) || 0; result = new BigNumber(number[0], radix) || 0;
if (number.length === 1) return result; if (number.length === 1) return result;
// Fractional part // Fractional part
for (let i = 0; i < number[1].length; i++) { for (let i = 0; i < number[1].length; i++) {
const digit = parseInt(number[1][i], radix); const digit = new BigNumber(number[1][i], radix);
result += digit / Math.pow(radix, i+1); result += digit.div(Math.pow(radix, i+1));
} }
return result; return result;

View File

@ -60,17 +60,16 @@ const Convert = {
/** /**
* Convert distance operation. * Convert distance operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runDistance: function (input, args) { runDistance: function (input, args) {
let inputUnits = args[0], let inputUnits = args[0],
outputUnits = args[1]; outputUnits = args[1];
input = input * Convert.DISTANCE_FACTOR[inputUnits]; input = input.mul(Convert.DISTANCE_FACTOR[inputUnits]);
return input / Convert.DISTANCE_FACTOR[outputUnits]; return input.div(Convert.DISTANCE_FACTOR[outputUnits]);
// TODO Remove rounding errors (e.g. 1.000000000001)
}, },
@ -141,16 +140,16 @@ const Convert = {
/** /**
* Convert data units operation. * Convert data units operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runDataSize: function (input, args) { runDataSize: function (input, args) {
let inputUnits = args[0], let inputUnits = args[0],
outputUnits = args[1]; outputUnits = args[1];
input = input * Convert.DATA_FACTOR[inputUnits]; input = input.mul(Convert.DATA_FACTOR[inputUnits]);
return input / Convert.DATA_FACTOR[outputUnits]; return input.div(Convert.DATA_FACTOR[outputUnits]);
}, },
@ -221,16 +220,16 @@ const Convert = {
/** /**
* Convert area operation. * Convert area operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runArea: function (input, args) { runArea: function (input, args) {
let inputUnits = args[0], let inputUnits = args[0],
outputUnits = args[1]; outputUnits = args[1];
input = input * Convert.AREA_FACTOR[inputUnits]; input = input.mul(Convert.AREA_FACTOR[inputUnits]);
return input / Convert.AREA_FACTOR[outputUnits]; return input.div(Convert.AREA_FACTOR[outputUnits]);
}, },
@ -332,16 +331,16 @@ const Convert = {
/** /**
* Convert mass operation. * Convert mass operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runMass: function (input, args) { runMass: function (input, args) {
let inputUnits = args[0], let inputUnits = args[0],
outputUnits = args[1]; outputUnits = args[1];
input = input * Convert.MASS_FACTOR[inputUnits]; input = input.mul(Convert.MASS_FACTOR[inputUnits]);
return input / Convert.MASS_FACTOR[outputUnits]; return input.div(Convert.MASS_FACTOR[outputUnits]);
}, },
@ -397,16 +396,16 @@ const Convert = {
/** /**
* Convert speed operation. * Convert speed operation.
* *
* @param {number} input * @param {BigNumber} input
* @param {Object[]} args * @param {Object[]} args
* @returns {number} * @returns {BigNumber}
*/ */
runSpeed: function (input, args) { runSpeed: function (input, args) {
let inputUnits = args[0], let inputUnits = args[0],
outputUnits = args[1]; outputUnits = args[1];
input = input * Convert.SPEED_FACTOR[inputUnits]; input = input.mul(Convert.SPEED_FACTOR[inputUnits]);
return input / Convert.SPEED_FACTOR[outputUnits]; return input.div(Convert.SPEED_FACTOR[outputUnits]);
}, },
}; };

View File

@ -37,7 +37,7 @@ TestRegister.addTests([
}, },
{ {
name: "Fork, (expect) Error, Merge", name: "Fork, (expect) Error, Merge",
input: "1\n2\na\n4", input: "1.1\n2.5\na\n3.4",
expectedError: true, expectedError: true,
recipeConfig: [ recipeConfig: [
{ {
@ -45,8 +45,8 @@ TestRegister.addTests([
args: ["\n", "\n", false], args: ["\n", "\n", false],
}, },
{ {
op: "To Base", op: "Object Identifier to Hex",
args: [16], args: [],
}, },
{ {
op: "Merge", op: "Merge",