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

`random(number(1)) * 1` throws a conversion error when BigNumber is configured #736

Closed ellis closed 8 years ago

ellis commented 8 years ago

The following code crashes:

var math = require('mathjs');
math.config({number: 'BigNumber', precision: 64});
math.eval("random(number(1)) * 1")

The error message is:

TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber (value: 0.3089532965760551). Use function bignumber(x) to convert to BigNumber.
    at typed.conversions.convert (./node_modules/mathjs/lib/core/typed.js:59:17)
    at Object.multiply (eval at _typed (./node_modules/typed-function/typed-function.js:1042:22), <anonymous>:62:27)
    at Object.defs.eval (eval at <anonymous> (./node_modules/mathjs/lib/expression/node/Node.js:70:19), <anonymous>:3:280)
    at typed.string (./node_modules/mathjs/lib/expression/function/eval.js:40:36)
    at Object.compile (eval at _typed (./node_modules/typed-function/typed-function.js:1042:22), <anonymous>:22:14)
    at Object.<anonymous> (./test.js:3:6)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)

I would like my users to be able to use random() in calculations without having to explicitly convert between number and bignumber. Does that make sense?

josdejong commented 8 years ago

Well, basically we should implement the BigNumber version of random to solve this correctly :)

When you multiply a number and a BigNumber, math.js converts the number to a BigNumber and then applies the multiplication to the two BigNumbers. The conversion warning you get is there for a reason: when you have a number with >15 digits, it's a number that contains round off errors. When converting such a value to a BigNumber, you would get a false idea of working at high precision. This error forces you to explicitly convert to a BigNumber yourself, to force you to understand what you're doing. In your example, not throwing this error would give the user a false idea that he's dealing with a 64 digit random number which is not the case.

ellis commented 8 years ago

Thanks for the info. As a side question, is there perhaps a configuration option to allow for the implicit conversion to take place anyway?

josdejong commented 8 years ago

There is currently no such option, I've updated a related issue, let's continue the discussion there ok?

See #710.