ChatGPT解决这个技术问题 Extra ChatGPT

Format number to always show 2 decimal places

I would like to format my numbers to always display 2 decimal places, rounding where applicable.

Examples:

number     display
------     -------
1          1.00
1.341      1.34
1.345      1.35

I have been using this:

parseFloat(num).toFixed(2);

But it's displaying 1 as 1, rather than 1.00.

I mean if I enter 1 it will not show the number as 1.00, But if I enter 1.345 then it will show 1.35
I've reworded your question to what I believe you were looking for. Please check to make sure I've understood you correctly.
precise rounding with ie support . gist.github.com/ArminVieweg/28647e735aa6efaba401

C
Corey
(Math.round(num * 100) / 100).toFixed(2);

Live Demo

var num1 = "1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2); span { border: 1px solid #000; margin: 5px; padding: 5px; }

Note that it will round to 2 decimal places, so the input 1.346 will return 1.35.


@Kooilnc: OP wants 1 to display as 1.00, and 1.341 to display as 1.34.
No need to use round() since toFixed() rounds it.
toFixed() does round it but don't forget it's returning a string...So this method is really only useful for display. If you want to perform further mathematical computations on the rounded value do not use toFixed().
according to MDN, Math.round will not always give accurate results due to rounding errors. I tested this with 1.005, which should round to 1.01, but it gives 1.00. Use my answer for consistent accuracy: stackoverflow.com/a/34796988/3549440.
This entire answer could be reduced to (+num).toFixed(2). It even retains the rounding bug in the original, see Nate's answer.
F
Florian
Number(1).toFixed(2);         // 1.00
Number(1.341).toFixed(2);     // 1.34
Number(1.345).toFixed(2);     // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35

document.getElementById('line1').innerHTML = Number(1).toFixed(2); document.getElementById('line2').innerHTML = Number(1.341).toFixed(2); document.getElementById('line3').innerHTML = Number(1.345).toFixed(2); document.getElementById('line4').innerHTML = Number(1.3450001).toFixed(2);



@Andre, Chrome 29.0.1547.57 gives me 1.34 for expression Number(1.345).toFixed(2).
toFixed does do rounding, which you can see on almost every test number.
Accidentally submitted that last comment before finishing.. 1.345 is an example of a number that can't be stored exactly in floating point, so I think the reason that it doesn't round as you expect, is that it's actually stored as a number slightly less than 1.345 and it rounds down. If you test instead with (1.34500001).toFixed(2) then you see it correctly rounds up to 1.35
Way late, but to shed some light on the "5" rounding, it always rounds to the nearest even number. 1.345 would round to 1.34, but so would 1.335. Half the time 5 goes up and half the time 5 goes down.
@Bardicer, 1.335 rounds to 1.33 using toFixed(2)
r
razu

This answer will fail if value = 1.005.

As a better solution, the rounding problem can be avoided by using numbers represented in exponential notation:

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

Cleaner code as suggested by @Kon, and the original author:

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)

You may add toFixed() at the end to retain the decimal point e.g: 1.00 but note that it will return as string.

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces).toFixed(decimalPlaces)

Credit: Rounding Decimals in JavaScript


Amazingly, everyone else in here failed to see that toFixed has that rounding problem. Your answer should be the accepted one.
Just tested to see if this was still the case. you are still correct for Chrome Version 59.0.3071.115 Your solution will round up for 1.005 (1.01) and round down for 1.00499999 (1.00)
jsfiddle.net/Artistan/qq895bnp/28 there are "times" when toFixed will work, but it is quite inconsistent. :)
surround Number in parseFloat is its returning string
This is a solid answer. A couple of improvements I can think of: (1) VS Code (TypeScript file) doesn't like Math.round() passing in a string. (2) Make number of decimal places dynamic (not hard-coded to 2). (3) toFixed() seems unnecessary. So what I came up with is Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
h
holmis83

For modern browsers, use toLocaleString:

var num = 1.345;
num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });

Specify a locale tag as first parameter to control the decimal separator. For a dot, use for example English U.S. locale:

num.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

which gives:

1.35

Most countries in Europe use a comma as decimal separator, so if you for example use Swedish/Sweden locale:

num.toLocaleString("sv-SE", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

it will give:

1,35


m
mplungjan

var num = new Number(14.12); console.log(num.toPrecision(2)); //outputs 14 console.log(num.toPrecision(3)); //outputs 14.1 console.log(num.toPrecision(4)); //outputs 14.12 console.log(num.toPrecision(5)); //outputs 14.120


That gives unexpected results, if your number can be 1.4, and 23.654, and 0, what precision would you take?
Note the OP is asking for "rounding where applicable". toPrecision only formats the number to a specific number of decimal places, simply leaving out redundant places, but not rounding them. This could be very useful too of course, but it's important to understand the difference.
Actually toPrecision does round, according to Mozilla. Test: (20.55).toPrecision(3) "20.6"
If you want to strip trailing zeros, cast it to a Number or Float after using toFixed: const formattedVal = Number(val.toFixed(2)); Do not use toPrecision, as it counts the non-decimal numbers when using the precision param.
I
Imbro

I would suggest you use

new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(num)

that way you will also have the local format of a country you specify, plus it would garantee to show exact 2 decimals (whether when num is 1 or 1.12345, it will show 1.00 and 1.12 respectively)

In this example I used German localization, because I wanted my numbers show with thousands delimiter, so this would be some outputs:

1 => 1,00
1.12 => 1,12
1.1234 => 1,12
1234 => 1.234,00
1234.1234 => 1.234,12

underrated answer. This method makes possible to format all what you want, from the format of thousands to the number of decimals
Ich küsse deine Augen.
Great answer. Thank you. As a side note: this English version of this uses: 'en-US' instead of 'de-DE'
@Dave I deliberately used German for atypical formatting to make a point, as I explained. One can use whichever localization one wants, there are hundreds of them. Another English example would be 'en-GB'
THanks alot, i lost two hours in searching how to format stupid number. Deam
m
mplungjan

For the most accurate rounding, create this function and use it to round to 2 decimal places:

function round(value, decimals) { return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals).toFixed(decimals); } console.log("seeked to " + round(1.005, 2));

> 1.01

Thanks to Razu, this article, and MDN's Math.round reference.


what about 1.0049999999999998934 ?
It does not go beyond 2 d.p
jsfiddle.net/Artistan/qq895bnp tested, this is the only consistent method I have seen. Thanks.
m
macio.Jun

Simplest answer:

var num = 1.2353453;
num.toFixed(2); // 1.24

Example: http://jsfiddle.net/E2XU7/


Well, toFixed was already suggested in stackoverflow.com/a/13292833/218196. What additional information does your question provide?
that answer does not include round functionality, my answer includes tho.
Uh? It's exactly the same answer. Calling toFixed on a number.
Correct, same function, but the result of that answer is misleading, I just rectified it by expressing the round functionality.
The question states : "...rounding where applicable". Your answer does not involve rounding.
P
PirateApp

A much more generic solution for rounding to N places

function roundN(num,n){
  return parseFloat(Math.round(num * Math.pow(10, n)) /Math.pow(10,n)).toFixed(n);
}


console.log(roundN(1,2))
console.log(roundN(1.34,2))
console.log(roundN(1.35,2))
console.log(roundN(1.344,2))
console.log(roundN(1.345,2))
console.log(roundN(1.344,3))
console.log(roundN(1.345,3))
console.log(roundN(1.3444,3))
console.log(roundN(1.3455,3))

Output

1.00
1.34
1.35
1.34
1.35
1.344
1.345
1.344
1.346

This alswer fails with certain numbers close to 0, roundN(-3.4028230607370965e+38,2) returns "-3.4028230607370965e+38" instead of the expected 0.00
interesting @Ferrybig i ll test the numbers you mentioned and think of a workaround, thanks for testing
Note that the before mentioned number should not show zero, but a huge number instead, this was just an error in my brain. But it still doesn't work, since it still doesn't show 2 decimals
m
mplungjan

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat

var number = 123456.789; console.log(new Intl.NumberFormat('en-IN', { maximumFractionDigits: 2 }).format(number));


S
Sam Sehnert

If you're already using jQuery, you could look at using the jQuery Number Format plugin.

The plugin can return formatted numbers as a string, you can set decimal, and thousands separators, and you can choose the number of decimals to show.

$.number( 123, 2 ); // Returns '123.00'

You can also get jQuery Number Format from GitHub.


It is overkill to use a plugin "just to have fixed length decimal part".
@Lashae, sure, if thats all you want to do. I posted this in case the OP or anyone else wanted the extra functionality that the plugin provides as well.
if the poster of the question had added the jQuery tag of course ;)
m
mplungjan

You are not giving us the whole picture.

javascript:alert(parseFloat(1).toFixed(2)) shows 1.00 in my browsers when I paste it into the location bar. However if you do something to it afterwards, it will revert.

alert(parseFloat(1).toFixed(2)) var num = 2 document.getElementById('spanId').innerHTML = (parseFloat(num).toFixed(2) - 1)

shows 1 and not 1.00

Works in FF 50, Chrome 49 and IE 8
K
KooiInc

Is this what you mean?

[edit 20200530] The answer @razu provided is the best imho. So here's a slightly refactored version.

The snippet code will still not return the right value for something like showAsFloat(2.3346) (result 2.33, but should be 2.34). So, see also.

const showAsFloat = (input, decimals = 2, asString = false) => { if (input === null || input.constructor === Boolean || isNaN(+input)) { return input; } const converted = +( `${Math.round( parseFloat( `${input}e${decimals}` ) )}e-${decimals}` ); return asString ? converted.toFixed(decimals) : converted }; document.querySelector('#result').textContent = [ 'command | result', '-----------------------------------------------', 'showAsFloat(1); | ' + showAsFloat(1), 'showAsFloat(1.314); | ' + showAsFloat(1.314), 'showAsFloat(\'notanumber\') | ' + showAsFloat('notanumber'), 'showAsFloat(\'23.44567\', 3) | ' + showAsFloat('23.44567', 3), 'showAsFloat(2456198, 5, true)| ' + showAsFloat('24568', 5, true), 'showAsFloat(2456198, 5) | ' + showAsFloat('24568', 5), 'showAsFloat(0, 2, true); | ' + showAsFloat(0, 2, true), 'showAsFloat(1.345); | ' + showAsFloat(1.345), 'showAsFloat(0.005); | ' + showAsFloat(0.005), 'showAsFloat(null); | ' + showAsFloat(null), ].join('\n');


                			                   			


Note that this solution will fail to round correctly in certain cases: 1.005 comes out to 1.00, and 1.345 as 1.34.
That's why @razu's answer should be the accepted one ...
m
mplungjan

Are you looking for floor?

var num = 1.42482; var num2 = 1; var fnum = Math.floor(num).toFixed(2); var fnum2 = Math.floor(num2).toFixed(2); console.log(fnum + " and " + fnum2); //both values will be 1.00


I don't think he wants to round down to the nearest integer.
yeah, I wasn't sure from the description, but I was just throwing it out there incase
B
Behnam Mohammadi

Convert a number into a string, keeping only two decimals:

var num = 5.56789;
var n = num.toFixed(2);

The result of n will be:

5.57

d
dota2pro

Just run into this one of longest thread, below is my solution:

parseFloat(Math.round((parseFloat(num * 100)).toFixed(2)) / 100 ).toFixed(2)

Let me know if anyone can poke a hole


A
ArNo
function currencyFormat (num) {
    return "$" + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

console.info(currencyFormat(2665));   // $2,665.00
console.info(currencyFormat(102665)); // $102,665.00

M
Minas Mina

Here's also a generic function that can format to any number of decimal places:

function numberFormat(val, decimalPlaces) {

    var multiplier = Math.pow(10, decimalPlaces);
    return (Math.round(val * multiplier) / multiplier).toFixed(decimalPlaces);
}

R
RobG

Where specific formatting is required, you should write your own routine or use a library function that does what you need. The basic ECMAScript functionality is usually insufficient for displaying formatted numbers.

A thorough explanation of rounding and formatting is here: http://www.merlyn.demon.co.uk/js-round.htm#RiJ

As a general rule, rounding and formatting should only be peformed as a last step before output. Doing so earlier may introduce unexpectedly large errors and destroy the formatting.


There are times when I shake my head at my own choice to get so deeply involved of late in this whole JS/Ecma platform. :( "Where specific formatting is required, you should write your own routine or use a library function that does what you need. The basic ECMAScript functionality is usually insufficient for displaying formatted numbers." What an asinine statement - not that you made it, but because that fact exists. Just sad. Get on the ball, Javascript! :)
R
Ropali Munshi

here is another solution to round only using floor, meaning, making sure calculated amount won't be bigger than the original amount (sometimes needed for transactions):

Math.floor(num* 100 )/100;

L
Leonardo Filipe

function number_format(string,decimals=2,decimal=',',thousands='.',pre='R$ ',pos=' Reais'){ var numbers = string.toString().match(/\d+/g).join([]); numbers = numbers.padStart(decimals+1, "0"); var splitNumbers = numbers.split("").reverse(); var mask = ''; splitNumbers.forEach(function(d,i){ if (i == decimals) { mask = decimal + mask; } if (i>(decimals+1) && ((i-2)%(decimals+1))==0) { mask = thousands + mask; } mask = d + mask; }); return pre + mask + pos; } var element = document.getElementById("format"); var money= number_format("10987654321",2,',','.'); element.innerHTML = money; #format{ display:inline-block; padding:10px; border:1px solid #ddd; background:#f5f5f5; }

Test 123456789


N
Nayana_Das

Try below code:

function numberWithCommas(number) { 

   var newval = parseFloat(Math.round(number * 100) / 100).toFixed(2);

   return newval.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

A
Allan Pereira
var quantity = 12;

var import1 = 12.55;

var total = quantity * import1;

var answer = parseFloat(total).toFixed(2);

document.write(answer);

v
vitek

I had to decide between the parseFloat() and Number() conversions before I could make toFixed() call. Here's an example of a number formatting post-capturing user input.

HTML:

<input type="number" class="dec-number" min="0" step="0.01" />

Event handler:

$('.dec-number').on('change', function () {
     const value = $(this).val();
     $(this).val(value.toFixed(2));
});

The above code will result in TypeError exception. Note that although the html input type is "number", the user input is actually a "string" data type. However, toFixed() function may only be invoked on an object that is a Number.

My final code would look as follows:

$('.dec-number').on('change', function () {
     const value = Number($(this).val());
     $(this).val(value.toFixed(2));
});

The reason I favor to cast with Number() vs. parseFloat() is because I don't have to perform an extra validation neither for an empty input string, nor NaN value. The Number() function would automatically handle an empty string and covert it to zero.


k
ksav

var num1 = "0.1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2); span { border: 1px solid #000; margin: 5px; padding: 5px; }


This piece of code is enough to achieve your requirement parseFloat(num.toFixed(2))
K
Kamil Kiełczewski

RegExp - alternative approach

On input you have string (because you use parse) so we can get result by using only string manipulations and integer number calculations

let toFix2 = (n) => n.replace(/(-?)(\d+)\.(\d\d)(\d+)/, (_,s,i,d,r)=> { let k= (+r[0]>=5)+ +d - (r==5 && s=='-'); return s + (+i+(k>99)) + "." + ((k>99)?"00":(k>9?k:"0"+k)); }) // TESTs console.log(toFix2("1")); console.log(toFix2("1.341")); console.log(toFix2("1.345")); console.log(toFix2("1.005"));

Explanation

s is sign, i is integer part, d are first two digits after dot, r are other digits (we use r[0] value to calc rounding)

k contains information about last two digits (represented as integer number)

if r[0] is >=5 then we add 1 to d - but in case when we have minus number (s=='-') and r is exact equal to 5 then in this case we substract 1 (for compatibility reasons - in same way Math.round works for minus numbers e.g Math.round(-1.5)==-1)

after that if last two digits k are greater than 99 then we add one to integer part i


Y
Yuichi

I do like:

var num = 12.749;
parseFloat((Math.round(num * 100) / 100).toFixed(2)); // 123.75

Round the number with 2 decimal points, then make sure to parse it with parseFloat() to return Number, not String unless you don't care if it is String or Number.


I guess if the purpose was to display with 2 decimals precision, parsing the float will mess with that. E.g. parseFloat("1.00") // 1
b
bortunac

Extend Math object with precision method

Object.defineProperty(Math, 'precision',{ value: function (value,precision,type){ var v = parseFloat(value), p = Math.max(precision,0)||0, t = type||'round'; return (Math[t](v*Math.pow(10,p))/Math.pow(10,p)).toFixed(p); } }); console.log( Math.precision(3.1,3), // round 3 digits Math.precision(0.12345,2,'ceil'), // ceil 2 digits Math.precision(1.1) // integer part )


l
lefrost

You can use numeral.js.

numeral(1.341).format('0.00') // 1.34
numeral(1.345).format('0.00') // 1.35

n
nageen nayak
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>


<input type="text" class = 'item_price' name="price" min="1.00" placeholder="Enter Price" value="{{ old('price') }}" step="">

<script> 
$(document).ready(function() {
    $('.item_price').mask('00000.00', { reverse: true });
});
</script>

You don't need to include two gigantic, unecessary browser-only libraries, respond to DOM events, and manipulate the DOM in order to format a number. You should read through some of the other answers before posting.