107

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).

Nathan
  • 6,772
  • 11
  • 38
  • 55
  • The point being that .toFixed returns a String, so just round-tripping it via a Number and then back to a String will reconvert it without the trailing zeros. – Neil Sep 05 '11 at 21:01
  • @Nathan: just for clarification. Do you just want to remove the trailing zeros in the *string* that you got with toFixed()? – Jiri Kriz Sep 05 '11 at 21:41

11 Answers11

179
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0
Gus
  • 7,289
  • 2
  • 26
  • 23
  • 4
    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_. – Константин Ван Aug 28 '17 at 03:38
  • 4
    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. – ygoe Apr 04 '19 at 11:09
42

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/

Nachshon Schwartz
  • 15,289
  • 20
  • 59
  • 98
24

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
Jiri Kriz
  • 9,192
  • 3
  • 29
  • 36
  • 7
    You're the only one who really answered the question.. thanks! – Mugen Mar 29 '13 at 08:51
  • 5
    This leaves the dot on round numbers ("100.00" => "100.") – pckill Aug 26 '13 at 14:38
  • 5
    @pckill if you don't want the dot you could include it in the regular expression to be replaced (`...replace(/\.?0+$/, "");`). – Zach Snow Oct 01 '13 at 21:01
  • 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. – robocat May 07 '15 at 03:48
  • @Mugen, what was the problem with Gus's answer? – trysis Aug 17 '15 at 16:29
  • @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 – Mugen Aug 17 '15 at 16:31
  • @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 Aug 17 '15 at 16:50
  • @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. – trysis Aug 17 '15 at 19:51
  • @trysis [Gus's answer](https://stackoverflow.com/a/7312534/1899424) produces a floating point number. The OP asked for a string, which this answer produces. – dcorking Jul 26 '17 at 11:26
14

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

kennebec
  • 102,654
  • 32
  • 106
  • 127
  • 1
    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. – Domino May 06 '15 at 18:01
12

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.

robocat
  • 5,293
  • 48
  • 65
C. J.
  • 893
  • 9
  • 4
  • 1
    @robocat I've just done a simple check; `+(4.1).toFixed(4)` is `4.1` in _Chrome 60_. – Константин Ван Aug 28 '17 at 03:41
  • I don't get it. What was the reason why this answer got downvoted? – Константин Ван Aug 28 '17 at 03:43
  • @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 Aug 28 '17 at 04:55
  • This answer still works with NaN, Infinity, -Infinity, 3e30, and 0. Some other answers fail on some corner cases. – robocat Aug 28 '17 at 04:56
  • (4).toFixed(2) -> "4.00" in Chrome 60.0.3112.113 – Daniel Que Aug 29 '17 at 18:13
  • @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 Mar 15 '18 at 02:09
  • [This is a fantastic resource about Number conversion](https://thecodebarbarian.com/convert-a-string-to-a-number-in-javascript.html) and the various corner cases - up to date and very detailed. – robocat Jan 28 '19 at 23:11
3

None of these really got me what I was looking for based on the question title, which was, for example, for 5.00 to be 5 and 5.10 to be 5.1. My solution was as follows:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

Note: The regex only works if places > 0

P.S. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Jenna Zeigen
  • 263
  • 1
  • 3
  • 7
1

most efficient and bets method I found is below

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
TGK-UK
  • 49
  • 4
0

There is a better method which keeps precision and also strips the zeros. This takes an input number and through some magic of casting will pull off any trailing zeros. I've found 16 to be the precision limit for me which is pretty good should you not be putting a satellite on pluto.

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));
Kevrone
  • 614
  • 2
  • 11
  • 22
0

The toFixed() method formats a number using fixed-point notation, and returns a string.

It applies a half-up rounding strategy.

(0.124).toFixed(2); // returns 0.12
(0.125).toFixed(2); // returns 0.13

As you described, it will indeed also result in (potentially unnecessary) trailing zeroes sometimes.

(0.001).toFixed(2); // returns 0.00

You may not want to get rid of those trailing zeroes, essentially you could just convert it back to a number. There are many ways to do this.

+(0.001).toFixed(2); // the shortest

For an overview, of the different methods to convert strings to numbers, please check this question, which has some excellent answers.

bvdb
  • 22,839
  • 10
  • 110
  • 123
0

You can use The toFixed() method to format a number using fixed-point notation. Keep in mind that the parameter may be a value between 0 and 20. This returns your rounded number as a string, but it will still contain the trailing zeros. You can then use parseFloat to get your rounded number without the trailing zeros. Examples:

function prettyRound(num, decimals) {
  return parseFloat(num.toFixed(decimals));
}

const numberToRound = 1.12006
console.log(prettyRound(numberToRound, 3))

const anotherToRound = 1.10006
console.log(prettyRound(anotherToRound, 4))
criss_dev
  • 71
  • 1
  • 3
0

I have tried almost all methods suggested by experts here and there.

Finally, I am satisfied with my own answer. As I came to know Math.round is more precise than .toFixed() method, I have used Math.round method.

Math.round(parseFloat(numberString)*100000)/100000; // to round upto 5 decimal places

Math.round(parseFloat(numberString)*1000)/1000; // to round upto 3 decimal places

For Example

  Math.round(parseFloat("1.234567")*100000)/100000 >>> 1.23457
  Math.round(parseFloat("1.234567")*1000)/1000 >>> 1.235
  Math.round(parseFloat("1.001")*100000)/100000 >>> 1.001
  Math.round(parseFloat("1.001")*1000)/1000 >>> 1.001
  Math.round(parseFloat("1.0010005")*100000)/100000 >>> 1.001
  Math.round(parseFloat("1.0010005")*1000)/1000 >>> 1.001
  Math.round(parseFloat("1.001000")*100000)/100000 >>> 1.001
  Math.round(parseFloat("1.001000")*1000)/1000 >>> 1.001
  Math.round(parseFloat("0.000100")*100000)/100000 >>> 1.0E-4
  Math.round(parseFloat("0.000100")*1000)/1000 >>> 0.0
Anit
  • 84
  • 9