Skip to content

Instantly share code, notes, and snippets.

@jiggzson
Created November 8, 2014 05:25
Show Gist options
  • Save jiggzson/451c782f3b1d571c32a4 to your computer and use it in GitHub Desktop.
Save jiggzson/451c782f3b1d571c32a4 to your computer and use it in GitHub Desktop.
var Fraction = {
convert: function( value, opts ) {
var frac;
if( value === 0 ) {
frac = [ 0, 1];
}
else {
if( value < 1e-6 || value > 1e20) {
var qc = this.quickConversion( Number( value ) );
if( qc[1] <= 1e20 ) {
var abs = Math.abs( value );
var sign = value/abs;
frac = this.fullConversion( abs.toFixed( (qc[1]+'').length-1 ));
frac[0] = frac[0]*sign;
}
else {
frac = qc;
}
}
else {
frac = this.fullConversion( value );
}
}
return frac;
},
// If the fraction is small or too large this gets called instead of
// fullConversion method
quickConversion: function( dec ) {
var x = (dec.toExponential()+'').split('e');
var d = x[0].split('.')[1];// get the number of places after the decimal
var l = d ? d.length : 0; // maybe the coefficient is an integer;
return [Math.pow(10,l)*x[0], Math.pow(10, Math.abs(x[1])+l)];
},
fullConversion: function( dec ) {
//function returns a good approximation of a fraction
//http://mathforum.org/library/drmath/view/61772.html
//Decimal To Fraction Conversion - A Simpler Version
//Dr Peterson
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 [num, den];
}
};
/*
Usage:
var f = Fraction.convert(0.625);
Output: [5, 8]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment