How can I round down a number in Javascript?
Asked Answered
D

12

285

How can I round down a number in JavaScript?

math.round() doesn't work because it rounds it to the nearest decimal.

I'm not sure if there is a better way of doing it other than breaking it apart at the decimal point at keeping the first bit. There must be...

Diploid answered 16/9, 2009 at 23:6 Comment(1)
Round towards zero or towards negative infinity?Automata
M
487

Using Math.floor() is one way of doing this.

More information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor

Manyplies answered 16/9, 2009 at 23:8 Comment(2)
It's also the slowest method; if you need to perform a lot of these, use the bitwise | operator (see my post).Pickett
The | operator also rounds towards zero, not negative infinity.Stcyr
I
70

Round towards negative infinity - Math.floor()

+3.5 => +3.0
-3.5 => -4.0

Round towards zero can be done using Math.trunc(). Older browsers do not support this function. If you need to support these, you can use Math.ceil() for negative numbers and Math.floor() for positive numbers.

+3.5 => +3.0 using Math.floor()
-3.5 => -3.0 using Math.ceil()
Internecine answered 16/9, 2009 at 23:16 Comment(4)
Thank you for the completeness but the capitalization is wrong ... and in java-script that makes a HUGE difference. Otherwise I would have upvoted here.Gnaw
I have updated the answer so that the capitalization is now correct.Asteria
@Gnaw HUGE or huge? :DWittman
You can get the same effect as round-to-zero via x | 0.Kiley
P
41

Math.floor() will work, but it's very slow compared to using a bitwise OR operation:

var rounded = 34.923 | 0;
alert( rounded );
//alerts "34"

EDIT Math.floor() is not slower than using the | operator. Thanks to Jason S for checking my work.

Here's the code I used to test:

var a = [];
var time = new Date().getTime();
for( i = 0; i < 100000; i++ ) {
    //a.push( Math.random() * 100000  | 0 );
    a.push( Math.floor( Math.random() * 100000 ) );
}
var elapsed = new Date().getTime() - time;
alert( "elapsed time: " + elapsed );
Pickett answered 16/9, 2009 at 23:15 Comment(9)
??? I just ran jsdb (www.jsdb.org) which uses Spidermonkey 1.7, and ran a loop to sum up the floor'ed value of x[i] on an array of 100000 floating point numbers, first with Math.floor(), then with bitwise or as you suggest. It took approx the same time, 125 msec.Ukrainian
Just repeated the test with 500000 floating point numbers, it took approx the same time, approx 625 msec.Ukrainian
So I don't see how 1.25usec is very slow.Ukrainian
Can't argue with your data :) I think I may be have confused JS's implementation with ActionScript's (built on EcmaScript; obviously implementation differs). Thanks for checking my work!Pickett
@Jason S: I don't think .5s is slow to do things, but it doesn't mean you shouldn't aim to be as quick as possible if you have the opportunity.Scholium
They don't do the same thing, either. | converts to a 32-bit integer, truncating; Math.floor rounds down. jsfiddle.net/minitech/UVG2wBallocks
I agree 100% with minitech's comment. The main issue is the fact that if the number cannot be represented as a 32-bit number, using this method will result in an unexpected. On the other hand, if you know beforehand that the number will never be outside of the 32-bit range, you can use this approach instead.Briolette
@Ballocks how do you think the processor rounds down internally? :D You guys found 2 sides of the same coinSycamore
@clockw0rk: Converts to a 32-bit integer, truncating: (-5.8 | 0) === -5, (12345678901.2 | 0) === -539222987; Math.floor(-5.8) === -6, Math.floor(12345678901.2) === 12345678901. I was pointing out concrete differences in behaviour. (Actually, there’s even a link explaining that in the comment…)Ballocks
G
24

You can try to use this function if you need to round down to a specific number of decimal places

function roundDown(number, decimals) {
    decimals = decimals || 0;
    return ( Math.floor( number * Math.pow(10, decimals) ) / Math.pow(10, decimals) );
}

examples

alert(roundDown(999.999999)); // 999
alert(roundDown(999.999999, 3)); // 999.999
alert(roundDown(999.999999, -1)); // 990
Gaw answered 13/2, 2014 at 16:47 Comment(3)
I think a one-liner like this doesn't require a function.Sherlynsherm
roundDown(4.56, 2) gives you 4.55, so I don't think it's a good solution.Vince
That's right, because 4.56 * 100 == 455.99999999999994 due to the internal floating point representation. See https://mcmap.net/q/36088/-how-to-round-to-at-most-2-decimal-places-if-necessaryToussaint
V
11

Rounding a number towards 0 (aka "truncating its fractional part") can be done by subtracting its signed fractional part number % 1:

rounded = number - number % 1;

Like Math.floor (rounds towards -Infinity) this method is perfectly accurate.

There are differences in the handling of -0, +Infinity and -Infinity though:

Math.floor(-0) => -0
-0 - -0 % 1    => +0

Math.floor(Infinity)    => Infinity
Infinity - Infinity % 1 => NaN

Math.floor(-Infinity)     => -Infinity
-Infinity - -Infinity % 1 => NaN
Viewer answered 29/10, 2014 at 23:8 Comment(1)
Great answer! Perhaps it should say "Truncating a number towards zero" rather than "Rounding ..."Aleydis
E
8
Math.floor(1+7/8)
Epicurean answered 16/9, 2009 at 23:14 Comment(7)
1+7/8 = 1 - Not much need for Math.floor() there :)Medicare
Actually it's (7/8)+1 which is not 1. Thank you 3rd grade algebraKreda
Umm, please actually try this in a javascript program. I did. Display (1 + 7/8) and you will see 1.875. Math.round(...) is 2, Math.floor(...) is 1. What are you guys talking about?Epicurean
Or open the Firefox Error Console. Or Firebug. It isn't hard to try. I tried it. 1 + 7/8 is 1.875 in js. Did you possibly forget that all math in js is in floating point?Epicurean
It's probably easy to forget that javascript does everything in floating point. In many other languages 1+7/8 is 1, but in js it really is 1.875.Epicurean
This has nothing to do with whether javascript uses floating point or not. It all boils down to operator precedence (en.wikipedia.org/wiki/Order_of_operations), so it should always be 1+(7/8), being valid in most programming languagesDisputation
Actually @Epicurean is right. The difference between languages is the data type, not operator precedence. For example SQL returns an integer when doing math operations with integers. select 1+7/8 /* = 1 */, 7/8 /* = 0 */, 1.0+7.0/8.0 /* = 1.875000 */. Of course @JasonBerry 's mistake was the operator precedence.Embree
S
7

To round down towards negative infinity, use:

rounded=Math.floor(number);

To round down towards zero (if the number can round to a 32-bit integer between -2147483648 and 2147483647), use:

rounded=number|0;

To round down towards zero (for any number), use:

if(number>0)rounded=Math.floor(number);else rounded=Math.ceil(number);
Stcyr answered 3/3, 2014 at 21:57 Comment(0)
J
6

Was fiddling round with someone elses code today and found the following which seems rounds down as well:

var dec = 12.3453465,
int = dec >> 0; // returns 12

For more info on the Sign-propagating right shift(>>) see MDN Bitwise Operators

It took me a while to work out what this was doing :D

But as highlighted above, Math.floor() works and looks more readable in my opinion.

Jelsma answered 5/3, 2012 at 14:38 Comment(1)
It also silently kills your number if it doesn't fit in 32 bits. Chromium console: 99999999999999999999999|0 => -167772160Kale
G
3

This was the best solution I found that works reliably.

function round(value, decimals) {
    return Number(Math.floor(parseFloat(value + 'e' + decimals)) + 'e-' + decimals);
 }

Credit to: Jack L Moore's blog

Ganef answered 29/7, 2020 at 17:27 Comment(0)
L
3
Math.round(3.14159 * 100) / 100  // 3.14

3.14159.toFixed(2);              // 3.14 returns a string
parseFloat(3.14159.toFixed(2));  // 3.14 returns a number

Math.round(3.14159)  // 3
Math.round(3.5)      // 4
Math.floor(3.8)      // 3
Math.ceil(3.2)       // 4
Languet answered 20/3, 2022 at 0:20 Comment(0)
M
1

You need to put -1 to round half down and after that multiply by -1 like the example down bellow.

<script type="text/javascript">

  function roundNumber(number, precision, isDown) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = 0;
    if (isDown) {
      tempNumber = -tempNumber;
      roundedTempNumber = Math.round(tempNumber) * -1;
    } else {
      roundedTempNumber = Math.round(tempNumber);
    }
    return roundedTempNumber / factor;
  }
</script>

<div class="col-sm-12">
  <p>Round number 1.25 down: <script>document.write(roundNumber(1.25, 1, true));</script>
  </p>
  <p>Round number 1.25 up: <script>document.write(roundNumber(1.25, 1, false));</script></p>
</div>
Mortar answered 25/10, 2017 at 13:0 Comment(1)
Honestly In this community, we prefer answers like @Manyplies given above.Chemism
V
1

Here is math.floor being used in a simple example. This might help a new developer to get an idea how to use it in a function and what it does. Hope it helps!

<script>

var marks = 0;

function getRandomNumbers(){    //  generate a random number between 1 & 10
    var number = Math.floor((Math.random() * 10) + 1);
    return number;
}

function getNew(){  
/*  
    This function can create a new problem by generating two random numbers. When the page is loading as the first time, this function is executed with the onload event and the onclick event of "new" button.
*/
document.getElementById("ans").focus();
var num1 = getRandomNumbers();
var num2 = getRandomNumbers();
document.getElementById("num1").value = num1;
document.getElementById("num2").value = num2;

document.getElementById("ans").value ="";
document.getElementById("resultBox").style.backgroundColor = "maroon"
document.getElementById("resultBox").innerHTML = "***"

}

function checkAns(){
/*
    After entering the answer, the entered answer will be compared with the correct answer. 
        If the answer is correct, the text of the result box should be "Correct" with a green background and 10 marks should be added to the total marks.
        If the answer is incorrect, the text of the result box should be "Incorrect" with a red background and 3 marks should be deducted from the total.
        The updated total marks should be always displayed at the total marks box.
*/

var num1 = eval(document.getElementById("num1").value);
var num2 = eval(document.getElementById("num2").value);
var answer = eval(document.getElementById("ans").value);

if(answer==(num1+num2)){
    marks = marks + 10;
    document.getElementById("resultBox").innerHTML = "Correct";
    document.getElementById("resultBox").style.backgroundColor = "green";
    document.getElementById("totalMarks").innerHTML= "Total marks : " + marks;

}

else{
    marks = marks - 3;
    document.getElementById("resultBox").innerHTML = "Wrong";
    document.getElementById("resultBox").style.backgroundColor = "red";
    document.getElementById("totalMarks").innerHTML = "Total Marks: " + marks ;
}




}

</script>
</head>

<body onLoad="getNew()">
    <div class="container">
        <h1>Let's add numbers</h1>
        <div class="sum">
            <input id="num1" type="text" readonly> + <input id="num2" type="text" readonly>
        </div>
        <h2>Enter the answer below and click 'Check'</h2>
        <div class="answer">
            <input id="ans" type="text" value="">
        </div>
        <input id="btnchk" onClick="checkAns()" type="button" value="Check" >
        <div id="resultBox">***</div>
        <input id="btnnew" onClick="getNew()" type="button" value="New">
        <div id="totalMarks">Total marks : 0</div>  
    </div>
</body>
</html>
Vladimir answered 10/10, 2018 at 3:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.