JavaScript: Round to a number of decimal places, but strip extra zeros

98,662

Solution 1

>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0

Solution 2

Yes, there is a way. Use parseFloat().

parseFloat((1.005).toFixed(15)) //==> 1.005
parseFloat((1.000000000).toFixed(15)) //==> 1

See a live example here: http://jsfiddle.net/nayish/7JBJw/

Solution 3

As I understand, you want to remove the trailing zeros in the string that you obtained via toFixed(). This is a pure string operation:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123

Solution 4

Number(n.toFixed(15)) or +(n.toFixed(15)) will convert the 15 place decimal string to a number, removing trailing zeroes.

Solution 5

If you cast the return value to a number, those trailing zeroes will be dropped. This is also less verbose than parseFloat() is.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

This uses the unary + operator, so if using this as part of a string operation you need to have an infix + before it: var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. FYI a unary + in front of a string converts it to a Number. From MDN: Unary + can:

convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal ("0x"-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.

Share:
98,662
Nathan
Author by

Nathan

Updated on April 03, 2021

Comments

  • Nathan
    Nathan about 3 years

    Here's the scenario: I'm getting .9999999999999999 when I should be getting 1.0.
    I can afford to lose a decimal place of precision, so I'm using .toFixed(15), which kind of works.

    The rounding works, but the problem is that I'm given 1.000000000000000.
    Is there a way to round to a number of decimal places, but strip extra whitespace?

    Note: .toPrecision isn't what I want; I only want to specify how many numbers after the decimal point.
    Note 2: I can't just use .toPrecision(1) because I need to keep the high precision for numbers that actually have data after the decimal point. Ideally, there would be exactly as many decimal places as necessary (up to 15).

  • Mugen
    Mugen about 11 years
    You're the only one who really answered the question.. thanks!
  • pckill
    pckill over 10 years
    This leaves the dot on round numbers ("100.00" => "100.")
  • Zach Snow
    Zach Snow over 10 years
    @pckill if you don't want the dot you could include it in the regular expression to be replaced (...replace(/\.?0+$/, "");).
  • Domino
    Domino almost 9 years
    Thought I'd point it out, +(n.toFixed(...)) is much more efficient than parseFloat. Not sure why, but its also more efficient than Number in Chrome.
  • robocat
    robocat almost 9 years
    That fails on 0 and -0 because 0 becomes the empty string "", and -0 becomes -, neither of which are expected (at a guess). @zach-snow your suggested solution also fails on 0 and -0.
  • trysis
    trysis over 8 years
    @Mugen, what was the problem with Gus's answer?
  • Mugen
    Mugen over 8 years
    @trysis I don't really remember as it was two years ago. But just for instance, Gus's answer rounded the number, and that was not the requested operation
  • trysis
    trysis over 8 years
    @Mugen, if I am reading the question right, rounding the number is exactly what the OP wanted. He wanted to round to a certain amount of decimal places, which for some reason isn't possible with the built-in functions. This answer does the same thing.
  • trysis
    trysis over 8 years
    @Mugen, I apologize, I am not trying to bash you or anything, just trying to understand why you thought this was the only proper answer, what pitfalls, etc. you found in the others. If you can remember, I would be grateful, but if not, it's no big deal.
  • dcorking
    dcorking almost 7 years
    @trysis Gus's answer produces a floating point number. The OP asked for a string, which this answer produces.
  • Константин Ван
    Константин Ван over 6 years
    Don't forget to put them in parentheses when you treat negative numbers: -2.34.toFixed(1) returns -2.3 due to the operator precedence.
  • Константин Ван
    Константин Ван over 6 years
    @robocat I've just done a simple check; +(4.1).toFixed(4) is 4.1 in Chrome 60.
  • Константин Ван
    Константин Ван over 6 years
    I don't get it. What was the reason why this answer got downvoted?
  • robocat
    robocat over 6 years
    Fails on 5e30 (changes number to 5e3). Corner cases are diabolical!
  • robocat
    robocat over 6 years
    @K You were right so I deleted my previous comment and added to the answer (I think I was using infix + with a string on lhs, rather than correctly using unary +. Usually I am more careful! Cheers)
  • robocat
    robocat over 6 years
    This answer still works with NaN, Infinity, -Infinity, 3e30, and 0. Some other answers fail on some corner cases.
  • Daniel Que
    Daniel Que over 6 years
    (4).toFixed(2) -> "4.00" in Chrome 60.0.3112.113
  • Matt Huggins
    Matt Huggins over 6 years
    Doesn't work for parseFloat("0.0000007"), which gives "7e-7"
  • robocat
    robocat about 6 years
    @DanielQue you need to use +(4).toFixed(2). The unary + operator is critical as it strips the trailing zeros (while still treating Number corner-cases correctly). For example at the console try: console.log('answer:' + +(4).toFixed(2)); prints answer:4.
  • robocat
    robocat about 5 years
    This is a fantastic resource about Number conversion and the various corner cases - up to date and very detailed.
  • ygoe
    ygoe about 5 years
    Using the unary + operator should be faster than the parseFloat function: +number.toFixed(13) This expression can also be used to remove JavaScript number inaccuracies like in 1.0000000000000045.