2011-01-10 16 views

risposta

54
// Reduce a fraction by finding the Greatest Common Divisor and dividing by it. 
function reduce(numerator,denominator){ 
    var gcd = function gcd(a,b){ 
    return b ? gcd(b, a%b) : a; 
    }; 
    gcd = gcd(numerator,denominator); 
    return [numerator/gcd, denominator/gcd]; 
} 

reduce(2,4); 
// [1,2] 

reduce(13427,3413358); 
// [463,117702] 
+2

Questa è una funzione 'gcd' molto elegante. L'unico cambiamento che suggerirei è una qualche forma di controllo degli input per 'NaN' dato che' gcd (NaN, 1) 'produce' 1' dove mi aspetterei 'NaN' o un errore. – zzzzBov

+2

@zzzzBov Un caso limite interessante. Certamente si potrebbe aggiungere 'if (isNaN (numeratore) || isNaN (denominatore)) return NaN;' come prima riga. – Phrogz

+1

divertente, questa soluzione utilizza l'algoritmo di Euclide per trovare GCD: https://en.wikipedia.org/wiki/Euclidean_algorithm – camou

7

No, ma puoi scriverne uno abbastanza facilmente. Essenzialmente, è necessario dividere le parti superiore e inferiore della frazione con il loro "più grande comune denominatore" ... che è possibile calcolare dall'algoritmo di Euclide.

Leggi qui per ulteriori informazioni: http://www.jimloy.com/number/euclids.htm

edit:

codice (perché tutti sembrano essere farlo, questo non fa uso di ricorsione però)

var FractionReduce = (function(){ 
    //Euclid's Algorithm 
    var getGCD = function(n, d){ 
     var numerator = (n<d)?n:d; 
     var denominator = (n<d)?d:n;   
     var remainder = numerator; 
     var lastRemainder = numerator; 

     while (true){ 
      lastRemainder = remainder; 
      remainder = denominator % numerator; 
      if (remainder === 0){ 
       break; 
      } 
      denominator = numerator; 
      numerator = remainder; 
     } 
     if(lastRemainder){ 
      return lastRemainder; 
     } 
    }; 

    var reduce = function(n, d){ 
     var gcd = getGCD(n, d); 

     return [n/gcd, d/gcd]; 
    }; 

    return { 
      getGCD:getGCD, 
      reduce:reduce 
      }; 

}()); 

alert(FractionReduce.reduce(3413358, 13427)); 
+0

+1 per la gestione del numeratore> denominatore – Phrogz

5

Per ridurre una frazione, dividere il numeratore e il denominatore per il più grande fattore comune. Phrogz e David hanno già fornito il codice sorgente.

Tuttavia, se stai cercando librerie javascript per la gestione delle frazioni, ecco alcuni tra cui scegliere.

  1. Fraction.js
  2. Math.Rational
  3. Ratio.js
  4. Rational.js

Ecco un esempio di utilizzo Ratio.js.

var a = Ratio(2,4); 

a.toString() == "2/4"; 
a.simplify().toString() == "1/2"; // reduce() returns a clone of the Ratio() 
a.toString() == "2/4"; // Ratio functions are non-destructive. 
+0

Utile, grazie. Ho postato una domanda per chiedere l'efficienza relativa di queste librerie qui: http: // stackoverflow.it/questions/15840390/what-is-the-most-efficient-fraction-library-in-javascript? noredirect = 1 # comment22538987_15840390 – Omn

+1

@Omn Quindi hai già definito la performance utilizzando jsperf.com? Se vedi problemi con Ratio.js quando apri un ticket e cercherò di risolverlo. https://github.com/LarryBattle/Ratio.js –

+0

Non ho esperienza nella creazione e nell'esecuzione di benchmark. Ho finito per entrare nel codice e osservare ciò che sembrava avere una migliore codifica, commenti e funzioni implementate. Ho finito con Ratio.js ma non ho avuto la possibilità di lavorare su quel progetto da allora. Ti farò sicuramente sapere se trovo dei problemi e potrei solo contribuire con le correzioni dei bug se riesco a vedere il problema da solo. – Omn

1

So che c'è già una risposta, ma voglio condividere una libreria JS che ho trovato quando stavo cercando qualcosa da numeri decimali convertire in frazioni e riducendo frazioni.

La biblioteca chiama Fraction.js, che è stato davvero utile per me e mi ha risparmiato molto tempo e lavoro. Spero che possa essere molto utile a qualcun altro!

0

Ecco una funzione ricorsiva che utilizza ECMAScript 6 riduci. Funziona per la maggior parte delle frazioni purché il resto non sia troppo piccolo. 0 è stato ridefinito per farlo funzionare con array come [1.2, 2.4, 12, 24]. Ho eseguito il test su Chrome e IE Edge in modo che si possa comportare diversamente con altri browser o aggiornamenti. Quindi dovrebbe funzionare con una serie di float.

Array.prototype.gcd = function() { 
    if (this.length === 0) 
    return null; 
    return this.reduce((prev, curr) => { 
    if (curr <= 1.00000000001e-12) 
     return prev 
    else 
     return [curr, prev % curr].gcd(); 
    }); 
    } 

    var reducedValueGCD = [1.2, 2.4, 12, 24, 240].gcd(); 

Ricerca per riduzione MDN o ulteriori informazioni here.

Problemi correlati