Asymmetry in mathjs numeric type promotion strategies #3359
gwhitney
started this conversation in
Design decisions
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Consider (in the mathjs expression language)
7 + bignumber('1000000000000000000')
. This by default quietly promotes the 7 to a BigNumber and does the addition, presumably because the real number intended is unambiguous and there is no loss of precision in the addition; the resulting bignumber can represent the result exactly. And in fact, this promotion occurs quietly even when the string has 70 digits, when the resulting BigNumber does lose precision (in the default configuration) and the addition becomes meaningless (as can be demonstrated by noting that the value ofis true, which looks nonsensical on the face of it.
Contrast this to the current situation in which
7 + bigint('1000000000000000000')
fails with a complaint that we can't implicitly convert a bigint to a number when it is out of range of "safe" integers. But there is a perfectly sound way to compute an answer to this: instead convert the7
to a bigint and return 1000000000000000007n.This situation seems inconsistent and biased against bigints, to my eye. I do agree that there is a concern about what to do when someone writes
2.5 + bigint('1000000000000000000')
. But to my mind this concern should not prevent mathjs from doing something entirely reasonable and mathematically correct when it can.I think the ideal convention that mathjs could adopt would be in a mixed-operand computation, to promote types as conservatively as possible to produce a mathematically correct answer when possible, and if there is no such promotion available, fail with an appropriate warning.
It might be that it should be configurable what types to allow in this promotion scheme, and perhaps even configure the preferability of the various types.
To give some examples of what I think would be the ideal situation:
There are of course still tricky cases, such as would
2.5 * EvenGiantBigInt
promote to a bigint or a BigNumber/Fraction? But I think that it would be good to settle on a philosophy/set of principles here and then try to conform mathjs to that perspective. The current situation seems more or less ad hoc to the point of needing some regularization.Beta Was this translation helpful? Give feedback.
All reactions