Converting a Decimal to a Fraction - javascript

I'm working on a "toy problem" where I am supposed to write a JavaScript function that converts a decimal into a fraction and returns it as a string. For example: fractionConverter(2.75) should return "11/4".
Here is my code:
function fractionConverter (number) {
if (number > 0) {
var isNegative = false;
} else if (number < 0) {
var isNegative = true;
}
number = Math.abs(number);
if (number % 1 === 0) {
var finalFrac = number + "/1";
} else {
for (var i = 2; i < 10000000000; i++) {
if ((i * number) % 1 === 0) {
var finalFrac = (i * number) + "/" + i;
}
if (finalFrac) { break; }
}
}
var getFrac = function(numString, bool) {
if (!bool) {
return numString;
} else {
return "-" + numString;
}
}
return getFrac(finalFrac, isNegative);
}
Sorry about the formatting. Anyway, I'm getting a weird spec failure. The function returns the correct values for the following numbers: 0.5, 3, 2.5, 2.75, -1.75 and .88. For some reason, however, it is failing on 0.253213. It is returning 1266065/5000000 instead of 253213/1000000. Not really sure why.
Thanks

I am just improving #william's answer,
I think this script gives you more reduced fraction.
function fractionConverter(number) {
var fraction = number - Math.floor(number);
var precision = Math.pow(10, /\d*$/.exec(new String(number))[0].length);
var getGreatestCommonDivisor = function(fraction, precision) {
if (!precision)
return fraction;
return getGreatestCommonDivisor(precision, fraction % precision);
}
var greatestCommonDivisor = getGreatestCommonDivisor(Math.round(fraction * precision), precision);
var denominator = precision / getGreatestCommonDivisor(Math.round(fraction * precision), precision);
var numerator = Math.round(fraction * precision) / greatestCommonDivisor;
function reduce (numer,denom) {
for (var i = 2; i >= 9; i++) {
if ((numer%i===0) && (denom%i)===0) {
numerator=numer/i;
denominator=denom/i;
reduce(numerator,denominator);
};
};
}
reduce(numerator,denominator);
return numerator + "/" + denominator;
}
document.getElementById("output").innerHTML = fractionConverter(0.24888);
Here is the HTML
<body>
<p id="output"></p>
</body>
</html>

Javascript doesn't deal with floating point numbers accurately.
I tried typing this into node:
0.253213 * 1000000
And I got this:
253213.00000000003
Here is a different approach to testing for a multiplier
var bigNumber = Math.pow(10,8);
var isDivisible = (Math.round(i * number * bigNumber)/bigNumber % 1) == 0;
This will help you some of the way.
This also work the way you might expect it to, if you wanted 0.333333333 to be treated as 1/3.
One issue is that the highest integer you can have is javascript is between 10^15 and 10^16.
If ((number * bigNumber) > 2^53) this will not work.

The caveat to this answer is that ECMAscript inadequately handles Decimals.
Also, note that the following is largely pseudocode, but should work with minor fixes.
Here is a javascript solution to this problem:
var decimal_to_fraction = {
"numerator": 0,
"denominator": 0,
"simplified_numerator": this.numerator,
"simplified_denominator": this.denominator,
"init": function(numerator, denominator){
this.numerator = numerator
this.denominator = denominator
},
"get_divisor": function(numerator, denominator){
var divisor = 0;
var divisors = [1, 2, 3, 4, 5];
for (i in divisors) {
if (!(numerator % divisor) && !(denominator % divisor)) {
divisor = i;
break
}
}
return divisor
},
"calculate_fraction": function() {
var simplified = false;
divisor = this.get_divisor(numerator_denominator);
if (divisor) {
while (simplified == false) {
if (this.simplfieid_numerator / divisor and this.simplified_denominator / divisor) {
this.simplified_numerator = simplified_numerator / divisor
this.simplified_denominator = simplified_denominator / divisor
} else {
simplified = true
}
}
}
return (this.simplified_numerator, this.simplfieid_denominator)
},
"get_fraction": function() {
this.calculate_fraction()
fraction = "{0} / {1}".format(this.simplfieid_numerator, this.simplified_denominator"
return fraction
}
}
decimal_to_fraction.get_fraction()
In case you were curious, here's a Python solution to your problem:
class DecimalToFraction(object):
def __init__(decimal):
self.numerator = decimal * 100
self.denominator = 100
self.simplified_numerator = self.numerator
self.simplified_denominator = self.denominator
def get_divisor(self, numerator, denominator):
divisor = 0
for i in range(0,5):
if not numerator % divisor and not denominator % divisor:
divisor = i
break
return divisor
def calculate_fraction(self):
simplified = False
divisor = get_divisor(self.numerator, self.denominator)
if divisor:
while simplified == False:
if self.simplified_numerator / divisor and self.simplfieid_denominator / divisor:
self.simplified_numerator = simplified_numerator / divisor
self.simplified_denominator = simplified_denominator / divisor
else:
simplified = True
return (self.simplified_numerator, self.simplified_denominator)
def get_fraction(self):
self.calculate_fraction()
fraction = "{0} / {1}".format(self.simplified_numerator, self.simplified_denominator)
return fraction
#d2f = DecimalToFraction(<decimal>)
#d2f.get_fraction()

I completely changed the structure of your code, but this solution does work. It is based off of code from this thread. I hope this helps.
function fractionConverter(number) {
var fraction = number - Math.floor(number);
var precision = Math.pow(10, /\d*$/.exec(new String(number))[0].length);
var getGreatestCommonDivisor = function(fraction, precision) {
if (!precision)
return fraction;
return getGreatestCommonDivisor(precision, fraction % precision);
}
var greatestCommonDivisor = getGreatestCommonDivisor(Math.round(fraction * precision), precision);
var denominator = precision / greatestCommonDivisor;
var numerator = Math.round(fraction * precision) / greatestCommonDivisor;
return numerator + "/" + denominator;
}
document.getElementById("output").innerHTML = fractionConverter(0.253213);
<!DOCTYPE html>
<html>
<body>
<p id="output"></p>
</body>
</html>

You can use Erik Garrison's fraction.js library to do that and more fractional operations.
To to do 1.75 , you can just do
var f = new Fraction(1.75);
console.log(f.toFraction()); // Results "1 3/4"
console.log(f.s * f.n + " / " + f.d); // Results "7 / 4"
console.log(f.toString()); // Results "1.75

Related

Overwrite toFixed() with appropriate replacement to fix floating point error javascript

This is my attempt to fix the JavaScript toFixed() function...
Any input, ideas, corrections for possible errors are much appreciated!
Fix floating point inacurracy (example (35.355).toFixed(2) = 35.36, not 35.35)
No big additional libraries
Comprehensive function (readable by humans)
Mimics toFixed / i.e. outputs exactly the same (albeit with correction for floating point inac. or course)
This is my attempt -> Demo below (see console log)
Number.prototype.toFixed = function(fractionDigits) {
var digits = parseInt(fractionDigits) || 0;
var num = Number(this);
if( isNaN(num) ) {
return 'NaN';
}
var sign = num < 0 ? -1 : 1;
if (sign < 0) { num = -num; }
digits = Math.pow(10, digits);
num *= digits;
num = Math.round( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) );
var finalNumber = sign * num / digits;
// add 0 after last decimal number (not 0) for as many as requested (fractionDigits)
// in else case, check if requested digits exceed actual, then add 0 (avoid 10.1 for toFixed(2))
if(fractionDigits > 0 && finalNumber.toString().indexOf('.') == -1){
// check that .00 is present
finalNumber = finalNumber.toString() + '.' + '0'.repeat(fractionDigits);
} else if(fractionDigits > finalNumber.toString().split('.')[1]?.length){
finalNumber = finalNumber.toString() + '0'.repeat((fractionDigits - finalNumber.toString().split('.')[1]?.length));
}
return finalNumber.toString(); // tofixed returns as string always, do the same
}
console.log('(35.355).toFixed(2)', (35.355).toFixed(2));
console.log('(35.1).toFixed(2)', (35.1).toFixed(2));
console.log('(35).toFixed(2)', (35).toFixed(2));
Number.prototype.toFixed = function(fractionDigits) {
//function toFixed(numberInput, fractionDigits){
var digits = parseInt(fractionDigits) || 0;
var num = Number(this);
if( isNaN(num) ) {
return 'NaN';
}
var sign = num < 0 ? -1 : 1;
if (sign < 0) { num = -num; }
digits = Math.pow(10, digits);
num *= digits;
num = Math.round( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) );
var finalNumber = sign * num / digits;
// add 0 after last decimal number (not 0) for as many as requested (fractionDigits)
if(fractionDigits > 0 && finalNumber.toString().indexOf('.') == -1){
// check that .00 is present
finalNumber = finalNumber.toString() + '.' + '0'.repeat(fractionDigits);
} else if(fractionDigits > finalNumber.toString().split('.')[1]?.length){
finalNumber = finalNumber.toString() + '0'.repeat((fractionDigits - finalNumber.toString().split('.')[1]?.length));
}
return finalNumber.toString(); // tofixed returns as string always, do the same
}
console.log('post-fix | (35.355).toFixed(2)', (35.355).toFixed(2));
console.log('post-fix | (35.1).toFixed(2)', (35.1).toFixed(2));
console.log('post-fix | (35).toFixed(2)', (35).toFixed(2));
If it were me, I might have this string manipulation approach:
Number.prototype.toFixed = function(fractionDigits) {
var number = String(this);
var digits = fractionDigits || 0, length;
if(digits < 0 && digits > 100)
throw 'RangeError: toFixed() digits argument must be between 0 and 100';
var decimal = number.match(/(?<=\.)(\d*)/g);
var factor = Math.pow(10, digits);
if (decimal && decimal[0].length >= digits)
return String(Math.round(Number(number + '1') * factor) / factor);
else {
var length = digits - (decimal ? decimal[0].length : 0);
var delimiter = number.includes('.') || !length ? '' : '.';
return String(number) + delimiter + '0'.repeat(length);
}
}
function test() {
console.log((-35.555).toFixed(2))
console.log((-35.35).toFixed(2))
console.log((-35.9).toFixed(2))
console.log((-35).toFixed(2))
}
Note:
I think you're not going to encounter a string in your toFixed since it will not be triggered by it so you don't need isNaN check.
Catch beforehand when the parameter is less than 0 or greater than 100. This should throw an error like the original one.
Output:
Instead of rounding number num = Math.round( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) ); here you try parsing it to integer.
Math.round will round the value depending on its factorial part greater or less than 0.5. parseInt will simply fetch integer part without rounding, as you are expecting here.
console.log('(35.355).toFixed(2)', (35.355).toFixed(2));
console.log('(35.1).toFixed(2)', (35.1).toFixed(2));
console.log('(35).toFixed(2)', (35).toFixed(2));
Number.prototype.toFixed = function(fractionDigits) {
//function toFixed(numberInput, fractionDigits){
debugger;
var digits = parseInt(fractionDigits) || 0;
var num = Number(this);
if( isNaN(num) ) {
return 'NaN';
}
var sign = num < 0 ? -1 : 1;
if (sign < 0) { num = -num; }
digits = Math.pow(10, digits);
num *= digits;
num = parseInt( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) );
var finalNumber = sign * num / digits;
// add 0 after last decimal number (not 0) for as many as requested (fractionDigits)
if(fractionDigits > 0 && finalNumber.toString().indexOf('.') == -1){
// check that .00 is present
finalNumber = finalNumber.toString() + '.' + '0'.repeat(fractionDigits);
} else if(fractionDigits > finalNumber.toString().split('.')[1]?.length){
finalNumber = finalNumber.toString() + '0'.repeat((fractionDigits - finalNumber.toString().split('.')[1]?.length));
}
return finalNumber.toString(); // tofixed returns as string always, do the same
}
console.log('post-fix | (35.355).toFixed(2)', (35.355).toFixed(2));
console.log('post-fix | (35.1).toFixed(2)', (35.1).toFixed(2));
console.log('post-fix | (35).toFixed(2)', (35).toFixed(2));

convert decimal number to fraction in javascript or closest fraction [duplicate]

This question already has answers here:
How to simplify a decimal into the smallest possible fraction?
(6 answers)
Closed last year.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
So i want to be able to convert any decimal number into fraction. In both forms such as one without remainder like this: 3/5 or with remainder: 3 1/4.
what i was doing is this..
lets say i have number .3435.
Calculate amount of digits after decimals.
multiply by 10 with power of the amount before number.
then somehow find greatest common factor.
Now i don't know how to find GCF. And nor i know how to implement logic to find fraction that represents a number closely or in remainder form if exact fraction doesn't exists.
code i have so far: (testing)
x = 34/35;
a = x - x.toFixed();
tens = (10).pow(a.toString().length - 2);
numerator = tens * x;
denominator = tens;
Your first 2 steps are reasonable.
But what you should do is for the numerator and denominator calculate the Greatest Common Divisor (GCD) and then divide the numerator and denominator with that divisor to get the fraction you want.
GCD is rather easy to calculate. Here is Euclid's algorithm:
var gcd = function(a, b) {
if (!b) return a;
return gcd(b, a % b);
};
Edit
I've added a fully working JSFiddle.
Unless you are willing to work on developing something yourself then I would suggest using a library that someone has already put effort into, like fraction.js
Javascript
var frac = new Fraction(0.3435);
console.log(frac.toString());
Output
687/2000
On jsFiddle
You can use brute force test on different denominators and retain the result that has least error.
The algorithm below is an example of how you might go about this, but, suffers from being inefficient and limited to searching for denominators up to 10000.
function find_rational( value, maxdenom ) {
console.clear();
console.log( "Looking up: " + value );
let best = { numerator: 1, denominator: 1, error: Math.abs(value - 1) }
if ( !maxdenom ) maxdenom = 10000;
for ( let denominator = 1; best.error > 0 && denominator <= maxdenom; denominator++ ) {
let numerator = Math.round( value * denominator );
let error = Math.abs( value - numerator / denominator );
if ( error >= best.error ) continue;
best.numerator = numerator;
best.denominator = denominator;
best.error = error;
console.log( "Intermediate result: "
+ best.numerator + "/" + best.denominator
+ " (" + ( best.numerator/best.denominator)
+ " error " + best.error + " )" );
}
console.log( "Final result: " + JSON.stringify( best ) );
return best;
}
function calc() {
const value = parseFloat( $("#myInput").val() );
if ( isNaN(value) ) {
$( "#myResult" ).val( "NaN" );
return;
}
const rational = find_rational( value, 10000 );
$("#myResult").val( rational.numerator
+ " / " + rational.denominator
+ " ( Error: " + rational.error + " )" );
}
calc();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<P>
Enter a decimal number:<BR/>
<INPUT type="text" name="myInput" id="myInput" value=".3435" onkeyup="calc()"/><BR/>
</P>
<P>
Resulting Rational:<BR/>
<INPUT name="myResult" id="myResult" value=""/><BR/>
</P>
The above determines the .3435 as a fraction is 687 / 2000.
Also, had you gave it PI (e.g. 3.1415926) it produces good looking fractions like 22/7 and 355/113.
One quick and easy way of doing it is
getFraction = (decimal) => {
for(var denominator = 1; (decimal * denominator) % 1 !== 0; denominator++);
return {numerator: decimal * denominator, denominator: denominator};
}
I get very poor results using the GCD approach. I got much better results using an iterative approach.
For example, here is a very crude approach that zeros in on a fraction from a decimal:
function toFraction(x, tolerance) {
if (x == 0) return [0, 1];
if (x < 0) x = -x;
if (!tolerance) tolerance = 0.0001;
var num = 1, den = 1;
function iterate() {
var R = num/den;
if (Math.abs((R-x)/x) < tolerance) return;
if (R < x) num++;
else den++;
iterate();
}
iterate();
return [num, den];
}
The idea is you increment the numerator if you are below the value, and increment the denominator if you are above the value.
Use the Euclidean algorithm to find the greatest common divisor.
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];
}
This will provide you with the following results on your console
reduce(2,4);
// [1,2]
reduce(13427,3413358);
// [463,117702]
So by continuing from already what you have,
var x = 34/35;
var a = x - x.toFixed();
var tens = Math.pow(10,a.toString().length - 2);
var numerator = tens * x;
var denominator = tens;
reduce(numerator,denominator);
Source: https://stackoverflow.com/a/4652513/1998725
I had researched all over the website and I did combine all code into one, Here you go!
function fra_to_dec(num){
var test=(String(num).split('.')[1] || []).length;
var num=(num*(10**Number(test)))
var den=(10**Number(test))
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];
}
return (reduce(num,den)[0]+"/"+reduce(num,den)[1])
}
This code is very easy to use! You can even put number in this function!
The tricky bit is not letting floating points get carried away.
Converting a number to a string restrains the trailing digits,
especially when you have a decimal with an integer, like 1.0625.
You can round off clumsy fractions, by passing a precision parameter.
Often you want to force a rounded value up, so a third parameter can specify that.
(e.g.; If you are using a precision of 1/64, the smallest return for a non-zero number will be 1/64, and not 0.)
Math.gcd= function(a, b){
if(b) return Math.gcd(b, a%b);
return Math.abs(a);
}
Math.fraction= function(n, prec, up){
var s= String(n),
p= s.indexOf('.');
if(p== -1) return s;
var i= Math.floor(n) || '',
dec= s.substring(p),
m= prec || Math.pow(10, dec.length-1),
num= up=== 1? Math.ceil(dec*m): Math.round(dec*m),
den= m,
g= Math.gcd(num, den);
if(den/g==1) return String(i+(num/g));
if(i) i= i+' and ';
return i+ String(num/g)+'/'+String(den/g);
}
Math.roundFraction(.3435,64); value: (String) 11/32
Inspired by #chowey answer, which contained recursive implementation of finding close fraction for a decimal value within given tolerance, here is better (see benchmark), iterative version of it.
function toFractionIterative(x, epsilon = 0.0001) {
if (x == 0) return [0, 1];
const a = Math.abs(x);
let n = 0;
let d = 1;
let r;
while (true) {
r = n / d;
if (Math.abs((r - a) / a) < epsilon) {
break;
}
if (r < a) {
n++;
}
else {
d++;
}
}
return [x < 0 ? -n : n, d];
}
Benchmark (tl;dr: recursive 1,589 ops/s, iterative 5,955 ops/s; use iterative approach)
let v = 3.141592;
document.write(d2f(v)); // 392699/125000
function d2f(v) // decimal to fraction
{
if (Math.floor(v) == v) return v + '/' + 1;
v = Math.abs(v);
let ret = .01, // rounding error tolerance
td = v-Math.floor(v), // trailing digits
r = 1/td, // reciprocal
d = r, // start building denominator
lim = 20; // max loop limit
for (let i = 0; i < lim; i++)
{
td = r-Math.floor(r);
if (Math.abs(r-Math.round(r)) < ret) break;
r = 1/td;
d *= r;
}
return Math.round(d*v) + '/' + Math.round(d);
}
I came up with this for 16ths
function getfract(theNum){
var input=theNum.toString();
var whole = input.split(".")[0];
var rem = input.split(".")[1] * .1;
return(whole + " " + Math.round(rem * 16) + "/16");
}
function decimalToFraction(num) {
let numsAfterDecPoint = num.toString().split('.')[1] ? num.toString().split('.')[1].length : 0;
let numerator = num * Math.pow(10, numsAfterDecPoint);
let denominator = Math.pow(10, numsAfterDecPoint);
console.log(numerator + " / " + denominator)
let d = GCD(numerator,denominator)
return numerator / d + " / " + denominator / d
}
console.log(decimalToFraction(0.5)); // 5 / 10 => 1 / 2
console.log(decimalToFraction(178.45)); // 17845 / 100 => 3569 / 20
function GCD(a,b) {
let r = 0;
while(b != 0) {
r = a % b
a = b;
b = r;
}
return a;
}

Unexpected result when converting decimal to fraction

function gcd(a, b) {
return (b) ? gcd(b, a % b) : a;
}
var dec2Frac = function (d) {
var top = d.toString().replace(/\d+[.]/, '');
var bot = Math.pow(10, top.length);
if (d > 1) {
top = +top + Math.floor(d) * bot;
}
var x = gcd(top, bot);
var r1 = top / x;
var r2 = bot / x;
var frac = r1 + "/" + r2;
var parts = frac.split('/');
var simpler = parts[0][0]+'/'+parts[1][0];
return simpler;
};
If I input 640x960 = 0.66666666666667
I'm expecting the result to be 2/3 as evident here: http://www.mindspring.com/~alanh/fracs.html
Instead this function returns 6/1. Test here: http://jsbin.com/asoxud/1/
As an addition to MvG's Answer,
I found this quite interesting and wanted to understand how floating points are stored and how to get back an fraction of a float to maybe do calculations with them.
It gave a bit of brainache trying to figure this out on my own, but as it made click, i came up with this Fraction function,
I don't know if this helps you or not, but
now that its written anyway , why not leave it here
function Fraction(n, d) {
if ("number" !== typeof n)
throw new TypeError("Excptected Parameter to be of type number");
var strings = n.toString(2).split("."); //Split the number by its decimal point
if (strings.length > 1 && !d) { //No denominator given and n is a float
var floats = [strings[1].substr(0, 27), strings[1].substr(27, 54)]; //Split into to parts
var int64 = [
parseInt(floats[0], 2) << 1,
parseInt(floats[1], 2) << 1
];
var denominator = Math.pow(2, strings[1].length + 1); //
var numerator = int64[0] * Math.pow(2, floats[1].length);
numerator += int64[1];
numerator += parseInt(strings[0], 2) * denominator;
this.numerator = numerator;
this.denominator = denominator;
this.reduce();
this.approx = approx(n);
} else if (strings.length < 2 && !d) { // If no denominator and n is an int
this.numerator = n;
this.denominator = 1;
} else { //if n and d
this.numerator = n;
this.denominator = d;
}
function approx(f, n) {
n = n || 0;
var fraction = new Fraction(1, 1);
var float = Math.pow(f, -1);
var rec = ~~float;
var decimal = float - rec;
if (float.toPrecision(Fraction.precision) == rec)
return new Fraction(1, rec);
var _fraction = approx(decimal, n + 1);
fraction.denominator = rec * _fraction.denominator + _fraction.numerator;
fraction.numerator = _fraction.denominator;
return fraction;
}
}
//The approx precision
Fraction.precision = 10;
Fraction.prototype.toString = function () {
return this.numerator + "/" + this.denominator;
};
Fraction.prototype.gcd = function () {
return (function gcd(u, v) {
return ((u > 0) ? gcd(v % u, u) : v);
})(this.numerator, this.denominator);
};
Fraction.prototype.reduce = function () {
var _gcd = this.gcd();
this.numerator /= _gcd;
this.denominator /= _gcd;
};
Fraction.prototype.valueOf = function () {
return this.numerator / this.denominator;
};
var f = new Fraction(0.3333);
+ f; //0.3333333333
f.toString(); // 6004799502560181/18014398509481984
+ f.approx //0.33333
+ f.approx.toString() //3333/10000
var g = new Fraction(2 / 3);
+ g; //0.6666666666666666
g.toString(); //6004799503160661/9007199254740992
+ g.approx //0.6666666666666666
+ g.approx.toString() //2/3
Heres a JSbin as well
Your floating point numbers are approximations of the rational numbers you hope for. See e.g. Is floating point math broken? for details on this. The upshoot is: you can't hope to actually find a numerator and denominator which represent your original fraction.
If you want that fraction, you should have a look at continued fractions. Each truncated continued fraction will represent the best possible rational approximation for an arbitrary value. You can continue this until the error is sufficiently small.
Here is a page visualizing this approximation. The text is in German, but the maths should be clear enough. This page is in English but doesn't have as much visualization.

Math.ceil to nearest five at position 1

Okay....
I have a lot of uncontrolled numbers i want to round:
51255 -> 55000
25 -> 25
9214 -> 9500
13135 -> 15000
25123 -> 30000
I have tried modifying the numbers as string and counting length....
But is there a simple way using some Math function maybe?
Here's my late answer. Uses no Math methods.
function toN5( x ) {
var i = 5;
while( x >= 100 ) {x/=10; i*=10;}
return ((~~(x/5))+(x%5?1:0)) * i;
}
DEMO: http://jsbin.com/ujamoj/edit#javascript,live
[51255, 24, 25, 26, 9214, 13135, 25123, 1, 9, 0].map( toN5 );
// [55000, 25, 25, 30, 9500, 15000, 30000, 5, 10, 0]
Or this is perhaps a bit cleaner:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {x/=10; i*=10;}
return (x + (5-((x%5)||5))) * i;
}
DEMO: http://jsbin.com/idowan/edit#javascript,live
To break it down:
function toN5( x ) {
// v---we're going to reduce x to the tens place, and for each place
// v reduction, we'll multiply i * 10 to restore x later.
var i = 1;
// as long as x >= 100, divide x by 10, and multiply i by 10.
while( x >= 100 ) {x/=10; i*=10;}
// Now round up to the next 5 by adding to x the difference between 5 and
// the remainder of x/5 (or if the remainder was 0, we substitute 5
// for the remainder, so it is (x + (5 - 5)), which of course equals x).
// So then since we are now in either the tens or ones place, and we've
// rounded to the next 5 (or stayed the same), we multiply by i to restore
// x to its original place.
return (x + (5-((x%5)||5))) * i;
}
Or to avoid logical operators, and just use arithmetic operators, we could do:
return (x + ((5-(x%5))%5)) * i;
And to spread it out a bit:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {
x/=10;
i*=10;
}
var remainder = x % 5;
var distance_to_5 = (5 - remainder) % 5;
return (x + distance_to_5) * i;
}
var numbers = [51255, 25, 9214, 13135, 25123, 3, 6];
function weird_round(a) {
var len = a.toString().length;
var div = len == 1 ? 1 : Math.pow(10, len - 2);
return Math.ceil(a / 5 / div) * div * 5;
}
alert(numbers.map(weird_round));
Also updated for numbers below 10. Won't work properly for negative numbers either, just mention if you need this.
DEMO
I'm not sure why, but I thought it would be fun with regular expressions:
var result = +(number.toString().replace(/([1-9])([0-9])(.+)/, function() {
return Math.ceil(+(arguments[1] + '.' + arguments[2])) * 10 - (+arguments[2] < 5?5:0) + arguments[3].replace(/./g, '0');
}));
Working Demo
with(Math) {
var exp = floor(log(number)/log(10)) - 1;
exp = max(exp,0);
var n = number/pow(10,exp);
var n2 = ceil(n/5) * 5;
var result = n2 * pow(10,exp);
}
http://jsfiddle.net/NvvGf/4/
Caveat: only works for the natural numbers.
function round(number) {
var numberStr = number + "",
max,
i;
if (numberStr[1] > '4') {
numberStr[0] = parseInt(numberStr[0]) + 1;
numberStr[1] = '0';
} else {
numberStr[1] = '5';
}
for (i = 2; max = numberStr.length; i < max; i += 1) {
numberStr += '0';
}
return parseInt(numberStr);
}
Strange coincidence, I wrote something really similar not so long ago!
function iSuckAtNames(n) {
var n = n.toString(), len = n.length, res;
//Check the second number. if it's less than a 5, round down,
//If it's more/equal, round up
//Either way, we'll need to use this:
var res = parseFloat(n[0]) * Math.pow(10, len - 1); //e.g. 5 * 10^4 = 50000
if (n[1] <= 5) {
//we need to add a 5 right before the end!
res += 5 * Math.pow(10, len - 2);
}
else {
//We need another number of that size
res += Math.pow(10, len - 1);
}
return res;
}

Reverse decimal digits in javascript

How do I reverse the digits of a number using bitwise?
input:
x = 123;
output:
x = 321;
How Do this?
That's not inverting bits; that's reversing the order of decimal digits, which is completely different. Here's one way:
var x = 123;
var y = 0;
for(; x; x = Math.floor(x / 10)) {
y *= 10;
y += x % 10;
}
x = y;
If you actually want to invert bits, it's:
x = ~x;
As a function:
function reverse(n) {
for(var r = 0; n; n = Math.floor(n / 10)) {
r *= 10;
r += n % 10;
}
return r;
}
If you wanted to make a simple reversal:
var x = 123;
var y = x.toString();
var z = y.split("").reverse().join("");
var aa = Number(z);
document.write(aa);
http://jsfiddle.net/jasongennaro/gV39e/
Here is another way...
var reversed = num.toString().split('').reverse().join('');
jsFiddle.
If you wanted it again as a Number, use parseInt(reversed, 10). Keep in mind though, leading 0s are not significant in a decimal number, and you will lose them if you convert to Number.
you also use this function
function myfunction(a){
var x=a.toString();
var y= x.split("");
var z=y.reverse();
var result=z.join("");
return result;
}
myfunction(123);
Simple and quick solution: Let's assume that you want to reverse a number 4546. You will take the reminder from each division by 10 and append it to the result until the number is > 0. And simultaneously updating the num variable by dividing it by 10.
var x = '';
var num = 4546;
while(num>0){
x = x + (num%10);
num = parseInt(num/10);
}
console.log(x);
Reversing The Positive/ Negative Integer Number
function reverseInt(n) {
return parseInt(n.toString().split('').reverse().join()) * Math.sign(n)
}
If n is -5, then Math.sign(n)==> will return -1
If n is 5, then Math.sign(n)==> will return 1
Here are reversible array functions in JavaScript that handle integers or strings:
function reverse(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
var temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
function toDigitsArrayFromInteger(integer, isReverse)
{
var digits = [];
if (integer > 0)
{
var floor = window.Math.floor;
while (integer > 0)
{
digits.push(floor(integer % 10));
integer = floor(integer / 10);
}
// Array is populated in reverse order. Un-reverse it to make it normal.
if (!isReverse)
{
digits = reverse(digits);
}
}
else if (integer < 0)
{
digits = toDigitsArrayFromInteger(-integer, isReverse);
}
else if (integer === 0)
{
digits.push(0);
}
return digits;
}
function toDigitsArrayFromString(string, isReverse)
{
var digits = [];
string += ""; // Coerce to string.
var i = null;
var length = string.length;
for (i = 0; i < length; i += 1)
{
var integer = parseInt(string.charAt(i), 10);
if (isFinite(integer))
{
digits.push(integer);
}
}
if (isReverse)
{
digits = reverse(digits);
}
return digits;
}
Once you have the digits as an array, you can reverse the array easily to get the digits starting from the left or from the right.
The string function is more versatile because it can find any digit in a string, whereas the integer function is limited to integers.
Benchmarks:
http://jsperf.com/todigitsarray
The benchmarks between the two functions show that in Firefox 10 and Chrome 12, the string function is 30% to 60% faster than the integer function. In Opera 12, the integer function is slightly faster by about 10%.
//reverse integer
const revInt = (num)=>{
//turn into string
if(Math.sign(num)===1)
return parseInt(num.toString().split('').reverse().join(''));
else return -1*parseInt(num.toString().split('').reverse().join(''));
}
console.log(revInt(-501));
<html>
<script>
function reverseInt(n){
var r=0;
while(n!=0){
r*=10;
r+=n%10;
n=Math.floor(n/10);
}
return r;
}
</script>
</html>
try this
var n = 352;
function loop(n, r){
if(!n) return r;
r = (r ? r * 10 : 0) + n % 10;
return loop(Math.floor( n / 10), r);
}
console.log(loop(n));
OK, how about using and chaining these popular tricks in JavaScript in one-line function as below...
const reverseNum = num => +("" + ~~num.split("").reverse().join(""));
And call it like these:
reverseNum(123); //321
reverseNum(423.09); //324
reverseNum(23305.1); //50332
reverseNum(89112); //21198
reverseNum(568434.2389); //434865
This takes Number x as a parameter and returns the reversed number.
const reverse = (x) => Number(x.toString().split("").reverse().join(""));
Memory Usage: 35.3 MB, less than 100.00% of JavaScript online submissions for Reverse Integer on leetcode.com.
Runtime: 80 ms, faster than 61.48% of JavaScript online submissions for Reverse Integer.
Time complexity is O(log10(n)).
function reverse(x) {
let rev = 0;
const isNegative = Math.sign(x) === -1;
const isOverflow = n => n > 2**31;
x = Math.abs(x);
while (x) {
let pop = x % 10;
x = Math.floor(x / 10);
rev = rev * 10 + pop;
if (isOverflow(rev)) {
return 0;
}
}
return isNegative ? rev * -1 : rev;
}
The code block below should do the trick
<script type = "text/javascript">
var input;
input=window.prompt ("Please enter a number to be reversed.");
x=input.length;
while(x > 0)
{
x=x-1;
document.write(input[x]);
}
</script>

Categories

Resources