Convert a decimal number to a fraction / rational number

前端 未结 11 1786
情歌与酒
情歌与酒 2020-12-01 16:36

In JavaScript, is there any way to convert a decimal number (such as 0.0002) to a fraction represented as a string (such as \"2/10000\")?

I

相关标签:
11条回答
  • 2020-12-01 17:08

    This may be a little old but the code that was posted fails on 0 values I have fixed that error and will post the updated code below

    //function to get highest common factor of two numbers (a fraction)
    function HCF(u, v) { 
        var U = u, V = v
        while (true) {
            if (!(U%=V)) return V
            if (!(V%=U)) return U 
        } 
    }
    //convert a decimal into a fraction
    function fraction(decimal){
    
        if(!decimal){
            decimal=this;
        }
        whole = String(decimal).split('.')[0];
        decimal = parseFloat("."+String(decimal).split('.')[1]);
        num = "1";
        for(z=0; z<String(decimal).length-2; z++){
            num += "0";
        }
        decimal = decimal*num;
        num = parseInt(num);
        for(z=2; z<decimal+1; z++){
            if(decimal%z==0 && num%z==0){
                decimal = decimal/z;
                num = num/z;
                z=2;
            }
        }
        //if format of fraction is xx/xxx
        if (decimal.toString().length == 2 && 
            num.toString().length == 3) {
                //reduce by removing trailing 0's
                // '
        decimal = Math.round(Math.round(decimal)/10);
        num = Math.round(Math.round(num)/10);
    }
    //if format of fraction is xx/xx
    else if (decimal.toString().length == 2 && 
            num.toString().length == 2) {
        decimal = Math.round(decimal/10);
        num = Math.round(num/10);
    }
    //get highest common factor to simplify
    var t = HCF(decimal, num);
    
    //return the fraction after simplifying it
    
    if(isNaN(whole) === true)
    {
     whole = "0";
    }
    
    if(isNaN(decimal) === true)
    {
        return ((whole==0)?"0" : whole);
    }
    else
    {
        return ((whole==0)?"0 " : whole+" ")+decimal/t+"/"+num/t;
    }
    }
    
    0 讨论(0)
  • 2020-12-01 17:09

    I just want a leave one alternative that I found to convert decimal numbers into fractions and reducing fractions, it's a JS library.

    The library calls fraction.js, it was really helpful for me and save me a lot time and work. Hope can be useful to somebody else!

    0 讨论(0)
  • 2020-12-01 17:12

    You can use Erik Garrison's fraction.js library to do that and more fractional operations.

    var f = new Fraction(2, 10000);
    console.log(f.numerator + '/' + f.denominator);
    

    To to do .003 you can just do

    var f = new Fraction(.003);
    console.log(f.numerator + '/' + f.denominator);
    
    0 讨论(0)
  • 2020-12-01 17:17

    The good news is that it's possible, but you'll have to convert it to code.

    Let's go with 2.56 for no reason at all.

    Use the decimal portion of the number .56

    There are 2 digits in .56, write .56 as 56/100.

    So we have 2 + 56/100 and need to reduce this fraction to lowest terms by dividing both the numerator and denominator by the greatest common divisor, which is 4 in this case.

    So, this fraction reduced to lowest terms is 2 + 14/25.

    To add those whole 2, we multiply by the divisor and add to the 14

    (2*25 + 14)/25 = 64/25

    0 讨论(0)
  • 2020-12-01 17:19

    I used this site http://mathforum.org/library/drmath/view/51886.html to build a function but as the article mentions you will get an unreasonable large number for radicals or pi.

    Hope it helps though.

    function Fraction(){}
    Fraction.prototype.convert = function(x, improper)
    {
        improper = improper || false;
        var abs = Math.abs(x);
        this.sign = x/abs;
        x = abs;
        var stack = 0;
        this.whole = !improper ? Math.floor(x) : 0;
        var fractional = !improper ? x-this.whole : abs;
        /*recursive function that transforms the fraction*/
        function recurs(x){
            stack++;
            var intgr = Math.floor(x); //get the integer part of the number
            var dec = (x - intgr); //get the decimal part of the number
            if(dec < 0.0019 || stack > 20) return [intgr,1]; //return the last integer you divided by
            var num = recurs(1/dec); //call the function again with the inverted decimal part
            return[intgr*num[0]+num[1],num[0]]
        }
        var t = recurs(fractional); 
        this.numerator = t[0];
        this.denominator = t[1];
    }
    
    Fraction.prototype.toString = function()
    {
        var l  = this.sign.toString().length;
        var sign = l === 2 ? '-' : '';
        var whole = this.whole !== 0 ? this.sign*this.whole+' ': sign;
        return whole+this.numerator+'/'+this.denominator;
    }
    
    //var frac = new Fraction()
    //frac.convert(2.56, false)
    //console.log(frac.toString())
    //use frac.convert(2.56,true) to get it as an improper fraction
    

    If you just want a self-contained function that only returns the numerator and denominator then use the function below.

    var toFraction = function (dec) {
        var is_neg = dec < 0;
        dec = Math.abs(dec);
        var done = false;
        //you can adjust the epsilon to a larger number if you don't need very high precision
        var n1 = 0, d1 = 1, n2 = 1, d2 = 0, n = 0, q = dec, epsilon = 1e-13;
        while (!done) {
            n++;
            if (n > 10000) {
                done = true;
            }
            var a = parseInt(q);
            var num = n1 + a * n2;
            var den = d1 + a * d2;
            var e = (q - a);
            if (e < epsilon) {
                done = true;
            }
            q = 1 / e;
            n1 = n2;
            d1 = d2;
            n2 = num;
            d2 = den;
            if (Math.abs(num / den - dec) < epsilon || n > 30) {
                done = true;
            }
        }
        return [is_neg ? -num : num, den];
    };
    //Usage:
    //var frac = toFraction(0.5);
    //console.log(frac)
    //Output: [ 1, 2 ]
    
    0 讨论(0)
提交回复
热议问题