Replies: 7 comments
-
Whilst you configure to use BigNumbers, in chain you use regular numbers (which have a precision in the order of 16 bits which can explain this limit of 10^16). The following works as expected, the expression parser will create BigNumbers: mathjs.config({
number: 'BigNumber'
});
console.log(mathjs.format(mathjs.eval('(10^58) mod 531'))); // 1 or: mathjs.config({
number: 'BigNumber'
});
var p = mathjs.chain(math.bignumber(10))
.pow(math.bignumber(58))
.mod(math.bignumber(531))
.done();
console.log(mathjs.format(p)); // 1 The bignumber configuration is confusing, it's quite logical to expect that numbers are always turned into BigNumbers which is not the case. This has bitten other people as well. Maybe we should rethink this behavior and automatically turn all numbers into BigNumbers (or Fractions) when configured like that. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your quick answer Jos. |
Beta Was this translation helpful? Give feedback.
-
I'm jumping in late in the discussion, but I agree that regular numbers should be converted to BigNumbers automatically. Is this something |
Beta Was this translation helpful? Give feedback.
-
I don't have a clear idea how we could best tackle this challenge, but I indeed think that this may be something we can solve by extending typed-function with capability to do preprocessing of inputs depending on dynamic configuration. |
Beta Was this translation helpful? Give feedback.
-
I think it is still relevant, and not as a question but as an idea. I'll reopen it and turn it into a discussion topic. |
Beta Was this translation helpful? Give feedback.
-
Another point specific to the particular function that the original poster was interested in is that the value of 10^58 mod 531 should absolutely not be computed by raising 10 to the 58th power and then taking the remainder mod 531; the power should be computed by some squarings and multiplications, taking the remainder mod 531 each time. In other words, take 10^2 mod 531 (that's 100) and multiply it by 10 to get 10^3 and take the remainder mod 531 (that's 469), then square that (to get 10^6 mod 531) and take the remainder mod 531, then multiply that remainder by 10 (to get 10^7 mod 531) and take the remainder mod 531, then square that twice taking the remainder each time (to get 10^28 mod 531) and then multiply that by 10 (to get 10^29 mod 531) and take the remainder mod 531 and finally square that (to get 10^58) and taking the remainder mod 531. The repeated taking of remainders keeps the whole computation well within the range of ordinary JavaScript number, and using the square-and-multiply trick greatly reduces the total amount of multiplication. Number theorists routinely use a "powmod" function when they want to get the remainder of a power of a number. Moreover, mathjs could just automatically when it is compiling expressions convert |
Beta Was this translation helpful? Give feedback.
-
This came up again recently in #1485. It seems as though it would be possible (with some enhancements to typed-function) when config.number is 'BigNumber' to reprioritize number->bignumber conversion over accepting a number argument as is, if that's the desired behavior. |
Beta Was this translation helpful? Give feedback.
-
Hello there,
I was attacking Project Euler, problem 26:
I was trying to find the length of the repetend for each 1/d by calculating the smallest k for which 10ᵏ mod d == 1 but was getting weird/wrong results, e.g.
The expected answer is 1, per https://www.wolframalpha.com/input/?i=10%5E58+mod+531 but it's returning 0?
Reproduction with a more obviously wrong result:
The greatest power of 10 for which mod(3) gives the correct answer is 15.
Is there something I'm doing wrong here?
Beta Was this translation helpful? Give feedback.
All reactions