mathjs: Why does 1cm + 1mm give rounding error, but 1mm + 1cm does not?
When using eval with units, first unit in string is set as the “ground” unit for the calculation. For example:
const m = require('mathjs')
m.eval('1cm + 1mm').toString() // '1.0999999999999999 cm'
m.eval('1mm + 1cm').toString() // '11 mm'
The result is a funny difference in the output format. Of course one could force output format:
m.eval('1cm + 1mm').format(2) // '1.1 cm'
m.eval('1mm + 1cm').format(2) // '11 mm'
I guess this is because first calculation is done with decimal (1 mm as 0.1 cm, which is not precise in binary) and second calculation in integers. As I see it, a sensible heuristic could be:
- “Sort” inputs by SI-prefix, smallest SI-prefix first.
- Convert all inputs to this SI-prefix.
- Do calculation.
Does this heuristic make sense for mathjs, or should the user of mathjs implement similar heuristics himself?
BTW, see that Math Notepad does what I expected:

About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 23 (7 by maintainers)
Ok here we go 😃
So far no rounding errors.
When calling
.toString(), the unit is transformed back to eithermmorcm. The heuristics of the current implementation in mathjs will select the prefix of the first unit of the two added units.So in this case
0.011 * 100introduces a floating point rounding error, whilst0.011 * 1000doesn’t.All good, my bad. Did not aply the fix in all my code. Works now!