1

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:

  1. Why won't Decimal.js calculate past 504 digits when it advertises the capacity for up to and including 1e+9 digits?
  2. Is there an alternative node or JS API that would support this program to a greater precision?
msrd0
  • 7,816
  • 9
  • 47
  • 82
met4000
  • 83
  • 1
  • 8
  • I don't understand your point/question. When calling `nTan(504)`, you are setting the precision to 504 digits. here: `Decimal.set({precision: acc})` – Thomas Oct 14 '17 at 11:59
  • If I call nTan(504) Decimal.js produces a "Precision limit exceeded" error. Any value less then that (e.g. nTan(250)) will return as expected – met4000 Oct 14 '17 at 12:05
  • OK. This error is thrown in a function `getLn10` when you exceed the length of the internally stored string for the natural logarithm of 10. in the repository, this is 1024 characters. Could it be, that you are using an older version of the lib, that stores a shorter string? – Thomas Oct 14 '17 at 12:20
  • The error says it is from Decimal.js's tan function: at ..., at nTan, at Decimal.P.tangent.P.tan, at Decimal.P.sine.P.sin, at toLessThanHalfPi, at getPi, at Error: [DecimalError] Precision limit exceeded – met4000 Oct 14 '17 at 12:32

1 Answers1

2

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.

MikeM
  • 13,156
  • 2
  • 34
  • 47