Truncate number to two decimal places without rounding

Truncate number to two decimal places without rounding

Suppose I have a value of 15.7784514, I want to display it 15.77 with no rounding.
var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+”
“);
document.write(num.toFixed(2)+”
“);
document.write(num.toFixed(3)+”
“);
document.write(num.toFixed(10));

Results in –
15.8
15.78
15.778
15.7784514000

How do I display 15.77?

Solutions/Answers:

Solution 1:

Convert the number into a string, match the number up to the second decimal place:

function calc(theform) {
    var num = theform.original.value, rounded = theform.rounded
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
    rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>

The toFixed method fails in some cases unlike toString, so be very careful with it.

Solution 2:

Update 5 Nov 2016

New answer, always accurate

function toFixed(num, fixed) {
    var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
    return num.toString().match(re)[0];
}

As floating point math in javascript will always have edge cases, the previous solution will be accurate most of the time which is not good enough.
There are some solutions to this like num.toPrecision, BigDecimal.js, and accounting.js.
Yet, I believe that merely parsing the string will be the simplest and always accurate.

Related:  Percentage chance of saying something?

Basing the update on the well written regex from the accepted answer by @Gumbo, this new toFixed function will always work as expected.


Old answer, not always accurate.

Roll your own toFixed function:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}

Solution 3:

I opted to write this instead to manually remove the remainder with strings so I don’t have to deal with the math issues that come with numbers:

num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number

This will give you “15.77” with num = 15.7784514;

Solution 4:

October 2017

General solution to truncate (no rounding) a number to the n-th decimal digit and convert it to a string with exactly n decimal digits, for any n≥0.

function toFixedTrunc(x, n) {
  const v = (typeof x === 'string' ? x : x.toString()).split('.');
  if (n <= 0) return v[0];
  let f = v[1] || '';
  if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
  while (f.length < n) f += '0';
  return `${v[0]}.${f}`
}

where x can be either a number (which gets converted into a string) or a string.

Related:  JavaScript - onClick to get the ID of the clicked button

Here are some tests for n=2 (including the one requested by OP):

0           => 0.00
0.01        => 0.01
0.2372      => 0.23
0.5839      => 0.58
0.999       => 0.99
1           => 1.00
1.01        => 1.01
2           => 2.00
2.551       => 2.55
2.5         => 2.50
2.99999     => 2.99
4.27        => 4.27
15.7784514  => 15.77
123.5999    => 123.59

NOTE: according to ecma specs, .toString() returns an exponential form for numbers outside the (10^-6, 10^21] range. Because of that, any solution that uses .toString() (including the accepted one) needs to take an extra step if the input values can go outside that range. In particular, x can be converted to a string that doesn’t have exponential notation before passing it to the function, i.e. toFixedTrunc(noExpNotation(x), n). Some info on how to implement noExpNotation can be found here, but that’s beyond the scope of this answer.

Solution 5:

parseInt is faster then Math.floor

function floorFigure(figure, decimals){
    if (!decimals) decimals = 2;
    var d = Math.pow(10,decimals);
    return (parseInt(figure*d)/d).toFixed(decimals);
};

floorFigure(123.5999)    =>   "123.59"
floorFigure(123.5999, 3) =>   "123.599"

Solution 6:

Simple do this

number = parseInt(number * 100)/100;