Replies: 8 comments 3 replies
-
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.
-
And it came up yet again in #3374 (comment). Jos there contemplates a So some options:
(A) drop TypeScript compatibility and go back to the Pocomath typing system that had a NumInt type (inhabited by JavaScript number entities that happen to be integers) as well as a number type (of all JavaScript numbers), possibly adding a NumDecimal type of just non-integer numbers, with both NumInt and NumDecimal subtypes of (B) drop numberFallback -- when config.number is (C) Beef up method resolution to handle choice types like (D) I can't at the moment think of other possibilities, but am certainly open to them. Since I don't personally care much about Typescript, I am open to (A) but I would understand a desire to keep TypeScript typings narrow -- although there's only so much one can do: If we allow settings under which
In the end, I think it may just be that having settings under which lots of mathjs methods (not just sqrt, for example) return different types depending on the value of the input (and not just its type) is the underlying reason why nothing much has happened on this issue. But if you want to pick some means of dealing with all this now and finally nail it down once and for all, either in v15 or in a nanomath-based overhaul, I am game. I'm just not the right person to pick, since I have no issues with a |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
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