Skip to content

Commit

Permalink
Fix floating point errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Jazza-231 committed Nov 16, 2023
1 parent 289c81a commit a36eda3
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 43 deletions.
41 changes: 4 additions & 37 deletions addons/editor-number-arrow-keys/userscript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { shiftDecimalPointToRight, shiftDecimalPointToLeft } from "../../libraries/common/cs/math-on-decimals.js";

export default async function ({ addon }) {
const settings = {
none: 0,
Expand All @@ -13,40 +15,6 @@ export default async function ({ addon }) {
return numStr.toString().split(".")[1].length;
};

const shiftDecimalPointToRight = (num, times) => {
const isNumberNegative = num[0] === "-";
let numStr = isNumberNegative ? num.substring(1) : num;
for (let i = 0; i < times; i++) {
if (numStr.indexOf(".") === -1) numStr += 0;
else if (numStr.indexOf(".") === numStr.length - 2) numStr = numStr.replace(".", "");
else {
const index = numStr.indexOf(".");
const numArrFiltered = Array.from(numStr.replace(".", ""));
numArrFiltered.splice(index + 1, 0, ".");
numStr = numArrFiltered.join("");
}
}
return Number(numStr) * (isNumberNegative ? -1 : 1);
};
const shiftDecimalPointToLeft = (num, times) => {
const isNumberNegative = num[0] === "-";
let numStr = isNumberNegative ? num.substring(1) : num;
for (let i = 0; i < times; i++) {
if (numStr.indexOf(".") === 0) numStr = ".0" + numStr.substring(1);
else if (numStr.indexOf(".") === -1) {
const numArr = Array.from(numStr);
numArr.splice(numArr.length - 1, 0, ".");
numStr = numArr.join("");
} else {
const index = numStr.indexOf(".");
const numArrFiltered = Array.from(numStr.replace(".", ""));
numArrFiltered.splice(index - 1, 0, ".");
numStr = numArrFiltered.join("");
}
}
return Number(numStr) * (isNumberNegative ? -1 : 1);
};

const normalizeNumber = (numStr) => {
const isNumberNegative = numStr[0] === "-";
const numStrPositive = isNumberNegative ? numStr.substring(1) : numStr;
Expand Down Expand Up @@ -150,9 +118,8 @@ export default async function ({ addon }) {
: settings[addon.settings.get("regular")];
}

const newValueAsInt =
shiftDecimalPointToRight(e.target.value, 5) + shiftDecimalPointToRight(changeBy.toString(), 5);
const newValue = shiftDecimalPointToLeft(newValueAsInt.toString(), 5);
const newValueAsInt = shiftDecimalPointToRight(e.target.value, 5) + shiftDecimalPointToRight(changeBy, 5);
const newValue = shiftDecimalPointToLeft(newValueAsInt, 5);

if (e.target.className.includes("input_input-form_")) {
Object.getOwnPropertyDescriptor(e.target.constructor.prototype, "value").set.call(e.target, newValue.toString());
Expand Down
35 changes: 29 additions & 6 deletions addons/math-in-inputs/userscript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { shiftDecimalPointToRight, shiftDecimalPointToLeft } from "../../libraries/common/cs/math-on-decimals.js";

export default async function ({ addon }) {
function getRegexFromSettings() {
let textInInputs = addon.settings.get("textInInputs");
Expand Down Expand Up @@ -61,32 +63,53 @@ export default async function ({ addon }) {
return evaluate(newExpr);
} else if (exp.test(expr)) {
let newExpr = expr.replace(exp, function (match, base, pow) {
return Math.pow(Number(base), Number(pow));
/*
Fixing floating point errors on exponents is very hard
This code does in fact fix them for the base being a decimal,
but not the exponent. I can not think of a better solution,
so for now, just ignore the errors
*/
const isNonZeroDecimalPow = /^\d*\.\d*[1-9]\d*$|^\d*\.$/.test(pow);

if (isNonZeroDecimalPow) {
return shiftDecimalPointToLeft(Math.pow(Number(shiftDecimalPointToRight(base, 5)), pow), 5 * pow);
} else {
return Math.pow(Number(base), Number(pow));
}
});
return evaluate(newExpr);
} else if (expAlt.test(expr)) {
let newExpr = expr.replace(expAlt, function (match, base, pow) {
return Math.pow(Number(base), Number(pow));
// Check if pow is a number with a dot and not equal to zero
const isNonZeroDecimalPow = /^\d*\.\d*[1-9]\d*$|^\d*\.$/.test(pow);

if (isNonZeroDecimalPow) {
return shiftDecimalPointToLeft(Math.pow(Number(shiftDecimalPointToRight(base, 5)), pow), 5 * pow);
} else {
return Math.pow(Number(base), Number(pow));
}
});
return evaluate(newExpr);
} else if (mul.test(expr)) {
let newExpr = expr.replace(mul, function (match, a, b) {
return Number(a) * Number(b);
// The decimal point needs to be shifted to the left double that of which it was shifted to the right
return shiftDecimalPointToLeft(shiftDecimalPointToRight(a, 5) * shiftDecimalPointToRight(b, 5), 10);
});
return evaluate(newExpr);
} else if (div.test(expr)) {
let newExpr = expr.replace(div, function (match, a, b) {
return Number(a) / Number(b);
// Likewise, the decimal point does not need to be shifted at all for division
return shiftDecimalPointToRight(a, 5) / shiftDecimalPointToRight(b, 5);
});
return evaluate(newExpr);
} else if (add.test(expr)) {
let newExpr = expr.replace(add, function (match, a, b) {
return Number(a) + Number(b);
return shiftDecimalPointToLeft(shiftDecimalPointToRight(a, 5) + shiftDecimalPointToRight(b, 5), 5);
});
return evaluate(newExpr);
} else if (sub.test(expr)) {
let newExpr = expr.replace(sub, function (match, a, b) {
return Number(a) - Number(b);
return shiftDecimalPointToLeft(shiftDecimalPointToRight(a, 5) - shiftDecimalPointToRight(b, 5), 5);
});
return evaluate(newExpr);
} else {
Expand Down
36 changes: 36 additions & 0 deletions libraries/common/cs/math-on-decimals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export function shiftDecimalPointToRight(number, times) {
let num = number.toString();
const isNumberNegative = num[0] === "-";
let numStr = isNumberNegative ? num.substring(1) : num;
for (let i = 0; i < times; i++) {
if (numStr.indexOf(".") === -1) numStr += 0;
else if (numStr.indexOf(".") === numStr.length - 2) numStr = numStr.replace(".", "");
else {
const index = numStr.indexOf(".");
const numArrFiltered = Array.from(numStr.replace(".", ""));
numArrFiltered.splice(index + 1, 0, ".");
numStr = numArrFiltered.join("");
}
}
return Number(numStr) * (isNumberNegative ? -1 : 1);
}

export function shiftDecimalPointToLeft(number, times) {
let num = number.toString();
const isNumberNegative = num[0] === "-";
let numStr = isNumberNegative ? num.substring(1) : num;
for (let i = 0; i < times; i++) {
if (numStr.indexOf(".") === 0) numStr = ".0" + numStr.substring(1);
else if (numStr.indexOf(".") === -1) {
const numArr = Array.from(numStr);
numArr.splice(numArr.length - 1, 0, ".");
numStr = numArr.join("");
} else {
const index = numStr.indexOf(".");
const numArrFiltered = Array.from(numStr.replace(".", ""));
numArrFiltered.splice(index - 1, 0, ".");
numStr = numArrFiltered.join("");
}
}
return Number(numStr) * (isNumberNegative ? -1 : 1);
}

0 comments on commit a36eda3

Please sign in to comment.