0

What is the best way to work with multiplying and dividing fractions in Javascript?

An example of one of the errors I received when multiplying 1/5 times 1/10 can be seen with the following code in the console:

console.log( (1/5) * (1/10));

which prints 0.020000000000000004 instead of 0.02.

I'm trying to perform some chemistry equilibrium calculations (stoichiometry) on the client side, in Javascript. The math requires some matrix calculations including determining the nullspace, or kernel, of two matrices. I was able to find a library called sylvester.js for some of the matrix math but still was unable to find any javascript implementation for finding the kernel. As part of my implementation I need to be able to multiply fractions reliably.

I considered rounding to some precision but felt uneasy about that and started rewriting the code to only use integers and just multiply everything by a set number so I don't have to use fractions. This still doesn't seem like the best way though. What should I do?

EDIT I should mention that one of my requirements is that I have clear, readable code and that the domain is well understood in terms of fractions. I'd like to write the operations that are being performed in such a way that I'm not just working around floating point math being broken. My question is different than "Is floating point math broken?" in that I'm not asking whether or not there is a problem, I know there is a problem, but how do I get around the issue and still write clean code in terms of fractions. Also when searching for fractions in javascript the other answer doesn't even show up.

Patrick Graham
  • 972
  • 8
  • 18
  • then don't use floats... and since all numbers in JS are floats, you're basically SOL unless you implement your own math routines. – Marc B Jun 20 '16 at 14:39
  • You can use rounding only for display. – meskobalazs Jun 20 '16 at 14:42
  • Simply make division the last step in your calculation. `(1 / 5) * (1 / 10)` is the same as `1 / 50` and this will indeed result in `0.02`. – Sebastian Simon Jun 20 '16 at 14:44
  • @Xufox that is currently how I've started to rewrite it. One of the things I dislike about this approach the most is that it has added logic which obfuscates the main logic of what I'm trying to do. The mathmatics behind calculating the kernel are cleaner when written with fractions. Its harder to follow and I have some bugs, therefore they've become harder to fix. – Patrick Graham Jun 20 '16 at 14:51

1 Answers1

-3

It seems pretty natural to me to use a library which implements rational numbers if you want to work with them. Fraction.js may be a decent choice. I do not have any experience with this particular library but it seems pretty stable and lightweight. Also, I have written fractions in C++ so I know it shouldn't be any significant overhead.

Qumeric
  • 518
  • 5
  • 16
  • Thanks for the libarary tip, that might be the route I go, but what is your reasoning for why I should use a library? Do you have any experience with the library? – Patrick Graham Jun 20 '16 at 14:53
  • 1
    Well, it seems pretty natural to me to use a library which implements rational numbers if you want to work with them. I do not have any experience with this particular library but it seems pretty stable and lightweight. Also I have written fractions in C++ so I know it shouldn't be a significant overhead. – Qumeric Jun 20 '16 at 15:06
  • Thanks. What do you think about including what you wrote in your comment in your actual answer? – Patrick Graham Jun 20 '16 at 15:07
  • Thanks for the advice. I have updated the answer. – Qumeric Jun 20 '16 at 15:24