Question

We need to convert a calculated value which might be something like 3.33333000540733337 to 3 1/3. Any of the libraries I've tried such as https://github.com/peterolson/BigRational.js will convert that to the most accurate rational number whereas I'm only concerned with the approximate rational number, to .01 significant decimals.

In ruby we currently do Rational(1.333).rationalize(Rational(0.01)) which gives us 1 as whole number, 1 as numerator and 3 as denominator.

Any thoughts on an algorithm that might help would be great.

Was it helpful?

Solution

You can use a function like this using the https://github.com/peterolson/BigRational.js library:

function rationalize(rational, epsilon) {
    var denominator = 0;
    var numerator;
    var error;

    do {
        denominator++;
        numerator = Math.round((rational.numerator * denominator) / rational.denominator);
        error = Math.abs(rational.minus(numerator / denominator));
    } while (error > epsilon);
    return bigRat(numerator, denominator);
}

It will return a bigRat object. You can check your example with this:

console.log(rationalize(bigRat(3.33333000540733337),0.01));

OTHER TIPS

Use the .toFixed() method before using your library. See http://www.w3schools.com/jsref/jsref_tofixed.asp .

You could use .toFixed() to get a rounded, fixed precision version, then apply BigRational to that:

var n = 3.33333000540733337;
m = n.toFixed(2);       // 3.33

Alternatively, .toPrecision() will give a number to the specificied number of significant digits.

Reference: .toFixed() .toPrecision()

I will try again. Presumably you tagged the question as 'math'. So let's look at the math.

  1. Fractions are rational numbers.
  2. Rational numbers are all of the form n divided by m, (n / m), where n and m are integers and m is not zero.
  3. You want a "mixed fraction".
  4. You can't expect to "round to the nearest fraction", whole or mixed, until you decide upon the denominator (m). If you chose m = 100, then you can round to the nearest 100th. If you choose 1 then you can round to the nearest integer. 2 to the nearest half, etc.
  5. Now that you have chosen the denominator, let's call it m, multiply your value (v) by m.
  6. Round the result to the nearest integer, call it rv.
  7. Your whole part of your mixed fraction will be floor (rv/m). The fractional part will be the (rv modulo m)/m (modulo means divide first by second and take the remainder as the result)

    Example v = 3.45.

    You want to round it to the nearest 1/3, so m = 3

    rv = round to nearest integer (3.45 * 3) = round (10.35) = 10

    whole part = floor (10/3) = 3

    fractional part = (10 modulo 3) / 3 = 1/3

Time to dust off your math. This is really elementary school math, but that is a bit easily forgotten. Why do you want 3 1/3?

You are trying to convert a rational number (all floats are rational numbers) to another rational number (all fractions are rational numbers).

So pick your denominator. Everything follows from that! (Reduce to lowest terms - unless you want to look like you dropped out of elementary school.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top