I have been using Decimal.js to increase the precision of my function that calculates the mth positive root of a = tan(a)
through trial and error. It works, however it returns a "Precision limit exceeded" error for nTan(504)
(would return 4.4934... to 505 digits) and greater.
var Decimal = require("decimal.js");
var fs = require("fs");
function nTan (acc, m) {
var test = [1], acc = (parseInt(acc) || 15) + 1;
Decimal.set({precision: acc});
var n = new Decimal(fs.readFileSync("result.txt", "utf-8") || 4.4).toString();
while (n.length + test.length - 2 < acc) {
var dec = (new Decimal(n + test.join("")));
if (dec.tan().cmp(n + test.join("")) >= 0) {
test[test.length - 1]--;
test.push(1);
} else test[test.length - 1]++;
if (test[test.length - 1] == 10) { test[test.length - 1] = 9; test.push(1); }
}
return (new Decimal(n + test.slice(0, -1).join(""))).plus(Math.PI * (parseInt(m) || 0)).toString();
}
My question(s) are:
1000000000 is the maximum permitted value for the decimal.js precision setting, but that does not mean that the trigonometric methods can return a result to that number of significant digits.
The limit to the precision of the trigonometric methods is determined by the precision of the value of Pi in the source code. It is hard-coded in the decimal.js file as the string variable PI
, and has a precision of 1025 digits.
This means that the precision limit for the cos
, sin
and tan
methods is up to about 1000 digits, but the actual figure depends on the precision of the argument passed to them. To calculate the actual figure use
maximum_result_precision = 1000 - argument_precision
For example, the following both work fine
Decimal.set({precision: 991}).tan(123456789);
Decimal.set({precision: 9}).tan(991_digit_number);
as, for each, the result precision plus the argument precision, i.e. 991 + 9
and 9 + 991
, is less than or equal to 1000.
This is why your program fails when you try and calculate the tan
of an argument with more than 500 digits to a precision of more than 500 digits.
To do it would require Pi to a higher precision - and that can only be done, and can be done simply, by editing the value of PI
in the source code, i.e. add more digits to it. The time taken by the methods will then be the limiting factor.
I am the library's author and I need to add this to its documentation.