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

Configure implicit conversion between bignumbers, fractions, and numbers #710

Closed gitKad closed 2 years ago

gitKad commented 8 years ago

I can't multiply bignumbers and fractions. Here's a failing test I added to function\arithmetic\multiply.test.js:

it('should multiply mixed fractions and big numbers', function() {
  assert.equal(multiply(math.bignumber('2'), math.fraction(1,3)), math.fraction(2,3));
  assert.equal(multiply(math.fraction(1,3), math.bignumber('2')), math.fraction(2,3));
});
josdejong commented 8 years ago

Thanks for bringing this up.

This is quite funny. Currently, there is no relation defined in math.js to convert Fractions to BigNumbers or vice versa, since it's ambiguous whether you would like to convert to one or the other. But the internally used typed-function is so clever that it found a conversion that is defined for both: namely converting both to a Complex number :D. Not really the intention.

To solve this, we have the following options:

  1. Always convert to BigNumber when using mixed BigNumbers and Fractions
  2. Always convert to Fraction when using mixed BigNumbers and Fractions
  3. Don't convert, throw an error. Force the user to convert to either BigNumber or Fraction
  4. Make it configurable whether to convert to BigNumber or Fraction

I think option 1 (convert to BigNumber) would be the best default choice. If you want to have a Fraction as output, you can do so by first converting all arguments to Fractions.

EDIT: there is an option 4, making this behavior configurable

gitKad commented 8 years ago

I need more information about how mathjs behave before I can share which options makes more sense for my use case. Would the bignumber type be able to convert to exact fractions involving large numbers numerators or denominators?

Either way, wouldn't the following be a fourth acceptable option?

josdejong commented 8 years ago

It indeed depends on the use case what's desired behavior.

Both aren't nice solutions, that's why we originally didn't want to choose one or the other and throw an error instead. Maybe option 3 is still the best.

josdejong commented 8 years ago

There is another interesting discussion here: https://github.com/josdejong/mathjs/issues/694, which is about being able to have the num/den of a Fraction be represented with a BigNumber, and to be able to use BigNumbers and Fractions as the re/im parts of Complex values and the values of Units.

josdejong commented 8 years ago

I updated the title of this issue. I think what we should do here is: