47

I need to add zeroes, so that each number has at least two decimals, but without rounding. So for example:

5      --> 5.00
5.1    --> 5.10
5.11   --> 5.11 (no change)
5.111  --> 5.111 (no change)
5.1111 -->  5.1111  (no change) 

My function is missing an IF to check for less than two decimal places:

function addZeroes( num ) {
   var num = Number(num);
   if ( //idk ) {
      num = num.toFixed(2);
   }
   return num;
}

Thanks!

Posting an alternative answer, in addition to the two below. (Keep in mind that I'm no expert and this is just for text inputs, not for parsing complex values like colors that could have floating point issues, etc.)

function addZeroes( value ) {
    //set everything to at least two decimals; removs 3+ zero decimasl, keep non-zero decimals
    var new_value = value*1; //removes trailing zeros
    new_value = new_value+''; //casts it to string

    pos = new_value.indexOf('.');
    if (pos==-1) new_value = new_value + '.00';
    else {
        var integer = new_value.substring(0,pos);
        var decimals = new_value.substring(pos+1);
        while(decimals.length<2) decimals=decimals+'0';
        new_value = integer+'.'+decimals;
    }
    return new_value;
}

[This is not a duplicate question. The question you linked assumes "knowing that they have at least 1 decimal." Decimal points cannot be assumed in text inputs, and this was making errors.]

Jen
  • 1,663
  • 1
  • 17
  • 34

10 Answers10

57

Here you go:

function addZeroes(num) {
// Convert input string to a number and store as a variable.
    var value = Number(num);      
// Split the input string into two arrays containing integers/decimals
    var res = num.split(".");     
// If there is no decimal point or only one decimal place found.
    if(res.length == 1 || res[1].length < 3) { 
// Set the number to two decimal places
        value = value.toFixed(2);
    }
// Return updated or original number.
return value;
}

// If you require the number as a string simply cast back as so
var num = String(value);

See fiddle for demonstration.


edit: Since I first answered this, javascript and I have progressed, here is an improved solution using ES6, but following the same idea:

function addZeroes(num) {
  const dec = num.split('.')[1]
  const len = dec && dec.length > 2 ? dec.length : 2
  return Number(num).toFixed(len)
}

Updated fiddle


edit 2: Or if you are using optional chaining you can do it in one line like so:

const addZeroes = num => Number(num).toFixed(Math.max(num.split('.')[1]?.length, 2) || 2)

Updateder fiddle

Fergmux
  • 932
  • 9
  • 13
  • 4
    You saved my time – Tejas Mehta May 27 '17 at 12:57
  • @Frugras num return as string, is possible to return a number like 1.00 – Elankeeran Jun 14 '17 at 09:16
  • 1
    you can do like this also function(num){ return Number(num).toFixed(2) } – Anshul Jain Feb 02 '18 at 12:31
  • @cale_b Good point, I've added some comments to help explain, as well as neatening up the code somewhat. In regards to your reply to Elankeeran, the fiddle seems to produce the correct results when returning as a number, so no string conversion necessary? – Fergmux Feb 13 '18 at 06:57
  • @Frugras - Excellent point. I stand corrected. For some reason I thought if was returning a string formatted as desired. Interestingly, doing a `( addZeroes( 1 ) === '1.00' )` comparison returns true, but a `typeof` on the result of `addZeroes` outputs `number`. You are correct. – random_user_name Feb 13 '18 at 13:18
  • `num.split` is not a function – Toskan May 06 '20 at 05:25
  • @Toskan in this case `num` is actually a string representation of a float so it will work – Fergmux May 06 '20 at 13:39
  • up to you if you want to insist or want to add an if. Many people in SOF want to be scrum master instead of actually helping the thousands and thousands of people that land here. I always updated my answers to help people, even if the answer was, say, about apache, I would include nginx etc. if it was simple. But up to you. – Toskan May 06 '20 at 21:23
  • @Toskan you'll see in my answer I showed how to cast a number to a string and vice versa, so I think I provided enough information to be helpful. Thanks for your input though. – Fergmux May 07 '20 at 09:09
  • Oh I see. Well for anyone who is interested in a working snippet: random_user_name's answer works fine here https://stackoverflow.com/a/24039563/533426 and should imho be the accepted answer – Toskan May 07 '20 at 20:24
41

Maybe use .toLocaleString():

var num = 5.1;    
var numWithZeroes = num.toLocaleString("en",{useGrouping: false,minimumFractionDigits: 2});
console.log(numWithZeroes);

As a function/demo:

function addZeroes(num) {
   return num.toLocaleString("en", {useGrouping: false, minimumFractionDigits: 2})
}

console.log('before   after       correct');
console.log('5      ->', addZeroes(5) , '  --> 5.00');
console.log('5.1    ->', addZeroes(5.1) , '  --> 5.10');
console.log('5.11   ->', addZeroes(5.11) , '  --> 5.11 (no change)');
console.log('5.111  ->', addZeroes(5.111) , ' --> 5.111 (no change)');
console.log('5.1111 ->', addZeroes(5.1111) , '--> 5.1111 (no change)');
console.log('-5     ->', addZeroes(-5) , ' --> -5.00');

And if you must use .toFixed(), here's a one-liner:

var num = 5.1;    
var numWithZeroes = num.toFixed(Math.max(((num+'').split(".")[1]||"").length, 2));
console.log(numWithZeroes);

Or, again, as a function/demo:

function addZeroes(num) {
   return num.toFixed(Math.max(((num+'').split(".")[1]||"").length, 2));
}

console.log('before   after       correct');
console.log('5      ->', addZeroes(5) , '  --> 5.00');
console.log('5.1    ->', addZeroes(5.1) , '  --> 5.10');
console.log('5.11   ->', addZeroes(5.11) , '  --> 5.11 (no change)');
console.log('5.111  ->', addZeroes(5.111) , ' --> 5.111 (no change)');
console.log('5.1111 ->', addZeroes(5.1111) , '--> 5.1111 (no change)');
console.log('-5     ->', addZeroes(-5) , ' --> -5.00');
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
17

The below code provides one way to do what you want. There are others.

function addZeroes(num) {
    // Cast as number
    var num = Number(num);
    // If not a number, return 0
    if (isNaN(num)) {
        return 0;
    }
    // If there is no decimal, or the decimal is less than 2 digits, toFixed
    if (String(num).split(".").length < 2 || String(num).split(".")[1].length<=2 ){
        num = num.toFixed(2);
    }
    // Return the number
    return num;
}

console.log(addZeroes(5)); // Alerts 5.00
console.log(addZeroes(5.1)); // Alerts 5.10
console.log(addZeroes(5.11)); // Alerts 5.11
console.log(addZeroes(5.111)); // Alerts 5.111

http://jsfiddle.net/nzK4n/

Mufaddal Hamid
  • 281
  • 3
  • 12
random_user_name
  • 25,694
  • 7
  • 76
  • 115
  • Would it be possible to remove/leave off the main integer if it's zero? ie .5 --> .50 rather than the current result, .5 -- 0.50 – Chase Apr 02 '17 at 22:25
  • @Chase - certainly is possible, but that's a different question than the one being answered here. – random_user_name Apr 03 '17 at 13:18
  • 1
    I tried addZeroes(23) and it kept giving me zero, I had to change line 3 to var num = parseInt(num); and isNan to !Number.isInteger(num) for it to work for me. – brandito Apr 06 '18 at 06:39
  • Just tested the code again, is working properly. Interesting you had challenges. Note that your change to `!Number.isInteger(num)` will cause this to _not work_ for floats (such as `5.1`), because 5.1 is not an integer, it's a float.n – random_user_name Apr 06 '18 at 14:06
  • ` var num` makes no sense as num is already declared in the function argument. So just `num` – Toskan May 06 '20 at 05:26
11

decimalNumber = number => Number.isInteger(number) ? number.toFixed(2) : number
Alina S
  • 111
  • 1
  • 2
1

Here is a function that will do this, function expects a number

var addZeroes = function(num) {
  var numberAsString = num.toString();

  if(numberAsString.indexOf('.') === -1) {
    num = num.toFixed(2);
    numberAsString = num.toString();
  } else if (numberAsString.split(".")[1].length < 3) {
    num = num.toFixed(2);
    numberAsString = num.toString();
  }

  return numberAsString
};
Paul T
  • 1,455
  • 11
  • 15
1

this solution checks if the number is fixed

decimalNumber = number => Number.isInteger(number) && number % 1 === 0 ? number : number.toFixed(4);

Or Shalmayev
  • 295
  • 1
  • 12
0

For number type textbox

Append .00 if number present

function addZeroes(ev) {
    debugger;
    // Convert input string to a number and store as a variable.
    var value = Number(ev.value);
    // Split the input string into two arrays containing integers/decimals
    var res = ev.value.split(".");
    // If there is no decimal point or only one decimal place found.
    if (res.length == 1 || res[1].length < 3) {
        // Set the number to two decimal places
        value = value.toFixed(2);
    }
    // Return updated or original number.
    if (ev.value != "") {
        ev.value = String(value);
    }
}
<input type="number" step=".01" onchange="addZeroes(this)" />
Arun Prasad E S
  • 9,489
  • 8
  • 74
  • 87
  • Question: I tried adding commas like this (ev.value = String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");), but after leaving the textbox after entering numbers, if I try to go back in to edit I get NaN, and I'm sure that is due to the commas. How do I work around? – Jujucat Oct 07 '20 at 13:54
  • Cannot edit that for some reason: The replace isn't the issue after all. Happens without it. – Jujucat Oct 07 '20 at 14:10
0

For what is worth, this is my recursive solution to this:

const addZeros = (decimal, value, check = true) => {
  if (check && decimal <= value.length) return value;
  if (decimal <= 0) return value;
  const newValue = value.length <= decimal ? '0' + value : value;
  return addZeros(decimal - 1, newValue, false);
};
  • decimal is the number of decimal you want
  • value is the value you want
  • check is not suppose to be set, it's here to prevent some issue in the first call.

e.g:

  • addZeros(3, "3") ==> "003"
  • addZeros(3, "30") ==> "030"
  • addZeros(3, "300") ==> "300"
  • addZeros(3, "3000") ==> "3000"
Equinox
  • 11
  • 6
0

We can solve this using pipe in angular. we will pass digit information parameter to decimal pipe and see how it works -

Digit Info Parameter (3.2-5):

{{ decimal_value | number:'3.2-5' }}

In the above code we are instructing decimal pipe to show atleast 3 integer values before decimal points and minimum 2 fraction digit, maximum 5 fraction digits.

if decimal_value = 5.123 then it will print 005.12300
if decimal_value = 53.1 then it will print  053.10
surajmall
  • 178
  • 1
  • 7
0

Work for me - let a = 12 console.log(a.toLocaleString("en", {useGrouping: false, minimumFractionDigits: 2})) output - 12.00

Naveen Patel
  • 111
  • 2