Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 660
kcssm Avatar asked Feb 06 '11 10:02

kcssm


People also ask

How do I use toFixed without rounding?

The idea is to convert the number into string (via toString()) and use the RegExp to truncate the extra zeros (without rounding). Next, we find out the position of decimal dot (if any), and pad up the zeros for exactly n decimal places.

How do you truncate decimals?

To truncate a number, we miss off digits past a certain point in the number, filling-in zeros if necessary to make the truncated number approximately the same size as the original number. To truncate a number to 1 decimal place, miss off all the digits after the first decimal place.

Does toFixed round or truncate?

The toFixed() method converts a number to a string. The toFixed() method rounds the string to a specified number of decimals.

How do you round to 2 decimal places in JavaScript?

Use the toFixed() method to round a number to 2 decimal places, e.g. const result = num. toFixed(2) . The toFixed method will round and format the number to 2 decimal places.


1 Answers

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); };  // Applied to Dogbert's answer: 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),         adjustedNum = number * multiplier,         truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);      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

like image 164
Nick Knowlson Avatar answered Oct 15 '22 19:10

Nick Knowlson