I am having trouble coming up with a class to deal with floating point precision, specifically the pow
program which generates the nth power of a number (the base or exponent can be negative or exist as a decimal). I have viewed others’ explanations and copied a lot of code, however the function still generates results with floating point errors:
class Core{
to_fraction(decimal, tolerance = 0){
var skipped = false;
if (isNaN(decimal) || isNaN(tolerance)) return;
for (var denominator = 1; (decimal * denominator) % 1 != 0; denominator++) if (Math.abs(Math.round(decimal * denominator) / denominator - decimal) < tolerance){skipped = true; break};
if (skipped) return {numerator: Math.round(decimal * denominator), denominator: denominator, difference: Math.round(decimal * denominator) / denominator - decimal};
if (!skipped) return {numerator: decimal * denominator, denominator: denominator};
}
dplaces(a){
if (a.toString().split(".").length == 1) return 0;
return a.toString().split(".")[1].length;
}
}
class Correct{
cf(a, b){
return Math.pow(10, Math.max(core.dplaces(a), core.dplaces(b)));
}
divide(a, b){
var _cf = this.cf(a, b);
return (a * _cf) / (b * _cf);
}
multiply(a, b){
var _cf = this.cf(a, b);
return (a * _cf) * (b * _cf) / (_cf * _cf);
}
subtract(a, b){
var _cf = this.cf(a, b);
return ((a * _cf) - (b * _cf)) / _cf;
}
add(a, b){
var _cf = this.cf(a, b);
return ((a * _cf) + (b * _cf)) / _cf;
}
pow(a, b){
var fraction = core.to_fraction(b);
for (var count = 0, result = 1; count < fraction.numerator; count++) result = this.multiply(result, a);
result = result ** (1 / fraction.denominator); // Da problems starts here
return result;
}
factorial(number){
if (number % 1 || !(Math.abs(number) >= 0)) return NaN;
if (number > 170) return Infinity;
var result = 1;
while (number > 1) result *= number--;
return result;
}
}
const core = new Core(), correct = new Correct();
console.log(correct.pow(7.154840569262962e+21, 1 / 5));
It seems that the problem starts on the second filled line of the pow
function within the Correct
class, however I cannot find or think of a method to avoid or change the stuff on that line.
This is extremely frustrating and rather unfortunate. Please suggest an alternative method (preferably in JavaScript or Node js) to achieve such effects or modify that line. Thank you!