# Truncate (not round off) decimal numbers in javascript

I am trying to truncate decimal numbers to decimal places. Something like this:

``````5.467   -> 5.46
985.943 -> 985.94
``````

`toFixed(2)` does just about the right thing but it rounds off the value. I don't need the value rounded off. Hope this is possible in javascript. upd:

So, after all it turned out, rounding bugs will always haunt you, no matter how hard you try to compensate them. Hence the problem should be attacked by representing numbers exactly in decimal notation.

``````Number.prototype.toFixedDown = function(digits) {
var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
m = this.toString().match(re);
return m ? parseFloat(m) : this.valueOf();
};

[   5.467.toFixedDown(2),
985.943.toFixedDown(2),
17.56.toFixedDown(2),
(0).toFixedDown(1),
1.11.toFixedDown(1) + 22];

// [5.46, 985.94, 17.56, 0, 23.1]
``````

Old error-prone solution based on compilation of others':

``````Number.prototype.toFixedDown = function(digits) {
var n = this - Math.pow(10, -digits)/2;
n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
return n.toFixed(digits);
}
`````` Dogbert's answer is good, but if your code might have to deal with negative numbers, `Math.floor` by itself may give unexpected results.

E.g. `Math.floor(4.3) = 4`, but `Math.floor(-4.3) = -5`

Use a helper function like this one instead to get consistent results:

``````truncateDecimals = function (number) {
return Math[number < 0 ? 'ceil' : 'floor'](number);
};

var a = 5.467;
var truncated = truncateDecimals(a * 100) / 100; // = 5.46
``````

Here's a more convenient version of this function:

``````truncateDecimals = function (number, digits) {
var multiplier = Math.pow(10, digits),

return truncatedNum / multiplier;
};

// Usage:
var a = 5.467;
var truncated = truncateDecimals(a, 2); // = 5.46

// Negative digits:
var b = 4235.24;
var truncated = truncateDecimals(b, -2); // = 4200
``````

If that isn't desired behaviour, insert a call to `Math.abs` on the first line:

``````var multiplier = Math.pow(10, Math.abs(digits)),
``````

EDIT: shendz correctly points out that using this solution with `a = 17.56` will incorrectly produce `17.55`. For more about why this happens, read What Every Computer Scientist Should Know About Floating-Point Arithmetic. Unfortunately, writing a solution that eliminates all sources of floating-point error is pretty tricky with javascript. In another language you'd use integers or maybe a Decimal type, but with javascript...

This solution should be 100% accurate, but it will also be slower:

``````function truncateDecimals (num, digits) {
var numS = num.toString(),
decPos = numS.indexOf('.'),
substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
trimmedResult = numS.substr(0, substrLength),
finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

return parseFloat(finalResult);
}
``````

For those who need speed but also want to avoid floating-point errors, try something like BigDecimal.js. You can find other javascript BigDecimal libraries in this SO question: "Is there a good Javascript BigDecimal library?" and here's a good blog post about math libraries for Javascript ``````var a = 5.467;
var truncated = Math.floor(a * 100) / 100; // = 5.46
`````` You can fix the rounding by subtracting 0.5 for toFixed, e.g.

``````(f - 0.005).toFixed(2)
`````` Nice one-line solution:

``````function truncate (num, places) {
return Math.trunc(num * Math.pow(10, places)) / Math.pow(10, places);
}
``````

Then call it with:

``````truncate(3.5636232, 2); // returns 3.56
truncate(5.4332312, 3); // returns 5.433
truncate(25.463214, 4); // returns 25.4632
`````` Truncate using bitwise operators:

``````~~0.5 === 0
~~(-0.5) === 0
~~14.32794823 === 14
~~(-439.93) === -439
`````` @Dogbert's answer can be improved with `Math.trunc`, which truncates instead of rounding.

There is a difference between rounding and truncating. Truncating is clearly the behaviour this question is seeking. If I call truncate(-3.14) and receive -4 back, I would definitely call that undesirable. – @NickKnowlson

``````var a = 5.467;
var truncated = Math.trunc(a * 100) / 100; // = 5.46
``````
``````var a = -5.467;
var truncated = Math.trunc(a * 100) / 100; // = -5.46
`````` I found a problem: considering the next situation: 2.1 or 1.2 or -6.4

What if you want always 3 decimals or two or wharever, so, you have to complete the leading zeros to the right

``````// 3 decimals numbers
0.5 => 0.500

// 6 decimals
0.1 => 0.10000

// 4 decimales
-2.1 => -2.1000

// truncate to 3 decimals
3.11568 => 3.115
``````

This is the fixed function of Nick Knowlson

``````function truncateDecimals (num, digits)
{
var numS = num.toString();
var decPos = numS.indexOf('.');
var substrLength = decPos == -1 ? numS.length : 1 + decPos + digits;
var trimmedResult = numS.substr(0, substrLength);
var finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

if (decPos != -1){
var s = trimmedResult+"";
decPos = s.indexOf('.');
var decLength = s.length - decPos;

while (decLength <= digits){
s = s + "0";
decPos = s.indexOf('.');
decLength = s.length - decPos;
substrLength = decPos == -1 ? s.length : 1 + decPos + digits;
};
finalResult = s;
}
return finalResult;
};
``````

https://jsfiddle.net/huttn155/7/ I wrote an answer using a shorter method. Here is what I came up with

``````function truncate(value, precision) {
var step = Math.pow(10, precision || 0);
var temp = Math.trunc(step * value);

return temp / step;
}
``````

The method can be used like so

``````truncate(132456.25456789, 5)); // Output: 132456.25456
truncate(132456.25456789, 3)); // Output: 132456.254
truncate(132456.25456789, 1)); // Output: 132456.2
truncate(132456.25456789));    // Output: 132456
``````

Or, if you want a shorter syntax, here you go

``````function truncate(v, p) {
var s = Math.pow(10, p || 0);
return Math.trunc(s * v) / s;
}
`````` Here is simple but working function to truncate number upto 2 decimal places.

``````           function truncateNumber(num) {
var num1 = "";
var num2 = "";
var num1 = num.split('.');
num2 = num.split('.');
var decimalNum = num2.substring(0, 2);
var strNum = num1 +"."+ decimalNum;
var finalNum = parseFloat(strNum);
return finalNum;
}
`````` The resulting type remains a number...

``````/* Return the truncation of n wrt base */
var trunc = function(n, base) {
n = (n / base) | 0;
return base * n;
};
var t = trunc(5.467, 0.01);
`````` Lodash has a few Math utility methods that can round, floor, and ceil a number to a given decimal precision. This leaves off trailing zeroes.

They take an interesting approach, using the exponent of a number. Apparently this avoids rounding issues.

(Note: `func` is `Math.round` or `ceil` or `floor` in the code below)

``````// Shift with exponential notation to avoid floating-point issues.
var pair = (toString(number) + 'e').split('e'),
value = func(pair + 'e' + (+pair + precision));

pair = (toString(value) + 'e').split('e');
return +(pair + 'e' + (+pair - precision));
`````` The answer by @kirilloid seems to be the correct answer, however, the main code needs to be updated. His solution doesn't take care of negative numbers (which someone did mention in the comment section but has not been updated in the main code).

Updating that to a complete final tested solution:

``````Number.prototype.toFixedDown = function(digits) {
var re = new RegExp("([-]*\\d+\\.\\d{" + digits + "})(\\d)"),
m = this.toString().match(re);
return m ? parseFloat(m) : this.valueOf();
};
``````

Sample Usage:

``````var x = 3.1415629;
Logger.log(x.toFixedDown(2)); //or use whatever you use to log
``````

Fiddle: JS Number Round down

PS: Not enough repo to comment on that solution. Here my take on the subject:

``````convert.truncate = function(value, decimals) {
decimals = (decimals === undefined ? 0 : decimals);
return parseFloat((value-(0.5/Math.pow(10, decimals))).toFixed(decimals),10);
};
``````

It's just a slightly more elaborate version of

``````(f - 0.005).toFixed(2)
`````` The one that is mark as the solution is the better solution I been found until today, but has a serious problem with 0 (for example, 0.toFixedDown(2) gives -0.01). So I suggest to use this:

``````Number.prototype.toFixedDown = function(digits) {
if(this == 0) {
return 0;
}
var n = this - Math.pow(10, -digits)/2;
n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
return n.toFixed(digits);
}
`````` ``````const TO_FIXED_MAX = 100;

function truncate(number, decimalsPrecison) {
// make it a string with precision 1e-100
number = number.toFixed(TO_FIXED_MAX);

// chop off uneccessary digits
const dotIndex = number.indexOf('.');
number = number.substring(0, dotIndex + decimalsPrecison + 1);

// back to a number data type (app specific)
return Number.parseFloat(number);
}

// example
truncate(0.00000001999, 8);
0.00000001
``````

works with:

• negative numbers
• very small numbers (Number.EPSILON precision) just to point out a simple solution that worked for me

convert it to string and then regex it...

``````var number = 123.45678;
var number_s = '' + number;
var number_truncated_s = number_s.match(/\d*\.\d{4}/)
var number_truncated = parseFloat(number_truncated_s)
``````

It can be abbreviated to

``````var number_truncated = parseFloat(('' + 123.4568908).match(/\d*\.\d{4}/))
`````` Here is an ES6 code which does what you want

``````const truncateTo = (unRouned, nrOfDecimals = 2) => {
const parts = String(unRouned).split(".");

if (parts.length !== 2) {
// without any decimal part
return unRouned;
}

const newDecimals = parts.slice(0, nrOfDecimals),
newString = `\${parts}.\${newDecimals}`;

return Number(newString);
};

console.log(truncateTo(5.467)); // ---> 5.46

console.log(truncateTo(985.943)); // ---> 985.94

// other examples

console.log(truncateTo(5)); // ---> 5

console.log(truncateTo(-5)); // ---> -5

console.log(truncateTo(-985.943)); // ---> -985.94`````` ``````Number.prototype.truncate = function(places) {
var shift = Math.pow(10, places);

return Math.trunc(this * shift) / shift;
};
`````` You can work with strings. It Checks if '.' exists, and then removes part of string.

truncate (7.88, 1) --> 7.8

truncate (7.889, 2) --> 7.89

truncate (-7.88, 1 ) --> -7.88

``````function  truncate(number, decimals) {
const tmp = number + '';
if (tmp.indexOf('.') > -1) {
return +tmp.substr(0 , tmp.indexOf('.') + decimals+1 );
} else {
return +number
}
}
`````` Take in the number. Multiply by significant digits after the decimal so that you can truncate to zero places with `~~`. Divide that multiplier back out. Profit.

``````function truncator(numToTruncate, intDecimalPlaces) {
var numPower = Math.pow(10, intDecimalPlaces); // "numPowerConverter" might be better
return ~~(numToTruncate * numPower)/numPower;
}
``````

I'm trying to resist wrapping the `~~` call in parens; order of operations should make that work correctly, I believe.

`alert(truncator(5.1231231, 1)); // is 5.1`

`alert(truncator(-5.73, 1)); // is -5.7`

`alert(truncator(-5.73, 0)); // is -5`

EDIT: Looking back over, I've unintentionally also handled cases to round off left of the decimal as well.

`alert(truncator(4343.123, -2)); // gives 4300.`

The logic's a little wacky looking for that usage, and may benefit from a quick refactor. But it still works. Better lucky than good. I thought I'd throw in an answer using `|` since it is simple and works well.

``````truncate = function(number, places) {
var shift = Math.pow(10, places);

return ((number * shift) | 0) / shift;
};
`````` ``````Number.prototype.trim = function(decimals) {
var s = this.toString();
var d = s.split(".");
d = d.substring(0, decimals);
return parseFloat(d.join("."));
}

console.log((5.676).trim(2)); //logs 5.67
`````` ``````function toFixed(number, digits) {
var reg_ex = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)")
var array = number.toString().match(reg_ex);
return array ? parseFloat(array) : number.valueOf()
}

var test = 10.123456789
var __fixed = toFixed(test, 6)
console.log(__fixed)
// => 10.123456
`````` I think this function could be a simple solution:

``````function trunc(decimal,n=2){
let x = decimal + ''; // string
return x.lastIndexOf('.')>=0?parseFloat(x.substr(0,x.lastIndexOf('.')+(n+1))):decimal; // You can use indexOf() instead of lastIndexOf()
}

console.log(trunc(-241.31234,2));
console.log(trunc(241.312,5));
console.log(trunc(-241.233));
console.log(trunc(241.2,0));
console.log(trunc(241));`````` Here is what I use:

``````var t = 1;
for (var i = 0; i < decimalPrecision; i++)
t = t * 10;

var f = parseFloat(value);
return (Math.floor(f * t)) / t;
``````