josdejong / mathjs

An extensive math library for JavaScript and Node.js
https://mathjs.org
Apache License 2.0
14.44k stars 1.24k forks source link

Simplify does odd thing with too-precise constants #2998

Closed javazen closed 1 year ago

javazen commented 1 year ago

This is strange.

math.simplify( '1.1529215046068e+18 / 1.1529215046068e+15' ) correctly returns a constant node with value 1000

but if you add one more digit of precision

math.simplify( '1.15292150460684e+18 / 1.15292150460684e+15' ) it now returns something very odd, the expression '1.44115188075855e+17 / 1.44115188075855e+14'

Debugging into math.simplify, the odd 1.44115... constant first shows up after simplify.js line 558 is executed. It's in the loop where different rules are tried, i=22 and it applies the rule with name 'simplifyConstant'

I don't know if this is another example of issue #1620 or something different. I would have thought that if there were too many digits, either they would have been rounded or maybe converted to something like a BigNumber.

Thanks in advance for any light anyone can shine on this.

josdejong commented 1 year ago

Regular numbers have a precision of about 16 digits. If you're exceeding this precision, round-off errors can occur, like in your example.

If you configure to use BigNumbers, you'll have a higher precision:

math.config({number: 'BigNumber'})
console.log(math.simplify( '1.1529215046068e+18 / 1.1529215046068e+15' ).toString())   // "1000"
console.log(math.simplify( '1.15292150460684e+18 / 1.15292150460684e+15' ).toString()) // "1000"
javazen commented 1 year ago

Yes, that worked, thank you!

josdejong commented 1 year ago

👍