In JavaScript, when converting from a float to a string, how can I get just 2 digits after the decimal point? For example, 0.34 instead of 0.3445434.
问题:
回答1:
var result = Math.round(original*100)/100;
The specifics, in case the code isn\'t self-explanatory.
edit: ...or just use toFixed
, as proposed by Tim Büthe. Forgot that one, thanks (and an upvote) for reminder :)
回答2:
There are functions to round numbers. For example:
var x = 5.0364342423;
print(x.toFixed(2));
will print 5.04.
EDIT: Fiddle
回答3:
Be careful when using toFixed()
:
First, rounding the number is done using the binary representation of the number, which might lead to unexpected behaviour. For example
(0.595).toFixed(2) === \'0.59\'
instead of \'0.6\'
.
Second, there\'s an IE bug with toFixed()
. In IE (at least up to version 7, didn\'t check IE8), the following holds true:
(0.9).toFixed(0) === \'0\'
It might be a good idea to follow kkyy\'s suggestion or to use a custom toFixed()
function, eg
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
回答4:
One more problem to be aware of, is that toFixed()
can produce unnecessary zeros at the end of the number.
For example:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
\"15.630000\"
The idea is to clean up the output using a RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\\.?0*$/,\'\');
}
The RegExp
matches the trailing zeros (and optionally the decimal point) to make sure it looks good for integers as well.
humanize(23-7.37)
\"15.63\"
humanize(1200)
\"1200\"
humanize(1200.03)
\"1200.03\"
humanize(3/4)
\"0.75\"
humanize(4/3)
\"1.333333\"
回答5:
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
回答6:
There is a problem with all those solutions floating around using multipliers. Both kkyy and Christoph\'s solutions are wrong unfortunately.
Please test your code for number 551.175 with 2 decimal places - it will round to 551.17 while it should be 551.18 ! But if you test for ex. 451.175 it will be ok - 451.18. So it\'s difficult to spot this error at a first glance.
The problem is with multiplying: try 551.175 * 100 = 55117.49999999999 (ups!)
So my idea is to treat it with toFixed() before using Math.round();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
回答7:
The key here I guess is to round up correctly first, then you can convert it to String.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Now you can safely format this value with toFixed(p). So with your specific case:
roundOf(0.3445434, 2).toFixed(2); // 0.34
回答8:
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+\'.\'+float_part;
}
回答9:
Maybe you\'ll also want decimal separator? Here is a function I just made:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = \"\";
var part = \"\";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = \'0\'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = \'.\'
part = \'0\'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = \'-\'+resposta;
return resposta;
}
回答10:
There is no way to avoid inconsistent rounding for prices with x.xx5 as actual value using either multiplication or division. If you need to calculate correct prices client-side you should keep all amounts in cents. This is due to the nature of the internal representation of numeric values in JavaScript. Notice that Excel suffers from the same problems so most people wouldn\'t notice the small errors caused by this phenomen. However errors may accumulate whenever you add up a lot of calculated values, there is a whole theory around this involving the order of calculations and other methods to minimize the error in the final result. To emphasize on the problems with decimal values, please note that 0.1 + 0.2 is not exactly equal to 0.3 in JavaScript, while 1 + 2 is equal to 3.
回答11:
/** don\'t spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? \"-\" : \" \";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = \"0\"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+\".\"+decStr;
}
prettyFloat(0); // \"0.00\"
prettyFloat(-1); // \"-1.00\"
prettyFloat(-0.999); // \"-1.00\"
prettyFloat(0.5); // \"0.50\"
回答12:
I use this code to format floats. It is based on toPrecision()
but it strips unnecessary zeros. I would welcome suggestions for how to simplify the regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Usage example:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\\.?0*$/, \'\');
result = result.replace(/\\.?0*e/, \'e\');
result = result.replace(\'e+\', \'e\');
return result;
}
document.write(test(1.2000e45, 3, 2) + \'=\' + \'1.2e45\' + \'<br>\');
document.write(test(1.2000e+45, 3, 2) + \'=\' + \'1.2e45\' + \'<br>\');
document.write(test(1.2340e45, 3, 2) + \'=\' + \'1.23e45\' + \'<br>\');
document.write(test(1.2350e45, 3, 2) + \'=\' + \'1.24e45\' + \'<br>\');
document.write(test(1.0000, 3, 2) + \'=\' + \'1\' + \'<br>\');
document.write(test(1.0100, 3, 2) + \'=\' + \'1.01\' + \'<br>\');
document.write(test(1.2340, 4, 2) + \'=\' + \'1.23\' + \'<br>\');
document.write(test(1.2350, 4, 2) + \'=\' + \'1.24\' + \'<br>\');
回答13:
You can try this if you want don\'t want to use rounding
function myFunction() {
var str = 12.234556;
str = str.toString().split(\'.\');
var res = str[1].slice(0, 2);
document.getElementById(\"demo\").innerHTML = str[0]+\'.\'+res;
}
output:12.23
str.toString().split(\'.\')
will convert your float number into string then split it by \'.\'
Resulting variables will an array with two string type elements , first element will be 12 and second element will be 234556
str[1].slice(0, 2)
will slice your second (234556) string into first two char which is 23
Then just concatenating first and resulting string through str[0]+\'.\'+res
Hope this will help