在JavaScript中用两个小数格式化一个数字

这一行代码把数字四舍五入到小数点后两位。但我得到的数字是这样的:10.8、2.4等等。这些都不是我的小数点后两位的想法,所以我怎么能改善以下?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

我想要10.80、2.40等数字。jQuery的使用对我来说很好。

909842 次浏览

要使用定点表示法格式化一个数字,你可以简单地使用toFixed方法:

(10.8).toFixed(2); // "10.80"


var num = 2.4;
alert(num.toFixed(2)); // "2.40"

注意,toFixed()返回一个字符串。

重要的:注意toFixed在90%的情况下不会四舍五入,它会返回四舍五入的值,但在很多情况下,它不起作用。

例如:

# EYZ0

更新:

现在,您可以使用Intl.NumberFormat构造函数。它是ECMAScript国际化API规范 (ECMA402)的一部分。它有非常好的浏览器支持,包括IE11,它是Node.js完全支持

const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});


console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

你也可以使用toLocaleString方法,它在内部使用Intl API:

const format = (num, decimals) => num.toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});




console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

这个API还为您提供了各种格式选项,如千个分隔符、货币符号等。

toFixed(n)提供小数点后的n个长度;toPrecision (x) 提供x的总长度

使用下面的方法

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
// It will round to the tenths place
num = 500.2349;
result = num.toPrecision(4); // result will equal 500.2

如果你想要固定的号码,可以使用

result = num.toFixed(2);

@heridev和我用jQuery创建了一个小函数。

接下来你可以试试:

超文本标记语言

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
$('.two-digits').keyup(function(){
if($(this).val().indexOf('.')!=-1){
if($(this).val().split(".")[1].length > 2){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(2);
}
}
return this; //for chaining
});
});
< p > 在线演示:< / p >

http://jsfiddle.net/c4Wqn/

我通常把它添加到我的个人库中,在一些建议和使用@TIMINeutron解决方案之后,并使其适用于十进制长度,这一个最适合:

function precise_round(num, decimals) {
var t = Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

将工作的例外报告。

我没有找到这个问题的准确解决方案,所以我自己创造了一个:

function inprecise_round(value, decPlaces) {
return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}


function precise_round(value, decPlaces){
var val = value * Math.pow(10, decPlaces);
var fraction = (Math.round((val-parseInt(val))*10)/10);


//this line is for consistency with .NET Decimal.Round behavior
// -342.055 => -342.06
if(fraction == -0.5) fraction = -0.6;


val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
return val;
}

例子:

function inprecise_round(value, decPlaces) {
return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}


function precise_round(value, decPlaces) {
var val = value * Math.pow(10, decPlaces);
var fraction = (Math.round((val - parseInt(val)) * 10) / 10);


//this line is for consistency with .NET Decimal.Round behavior
// -342.055 => -342.06
if (fraction == -0.5) fraction = -0.6;


val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
return val;
}


// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10


console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06


console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

我不知道为什么我不能在之前的答案上添加评论(也许我是绝望的盲人,我不知道),但我用@Miguel的答案想出了一个解决方案:

function precise_round(num,decimals) {
return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

它的两条评论(来自@bighostkim和@Imre):

  • precise_round(1.275,2)不返回1.28的问题
  • 问题与precise_round(6,2)不返回6.00(他想)。

我最终的解决方案如下:

function precise_round(num,decimals) {
var sign = num >= 0 ? 1 : -1;
return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

正如你所看到的,我不得不加了一点“纠正”。(这不是它是什么,但自从数学。round是有损的-你可以在jsfiddle.net上检查它-这是我知道如何“修复”的唯一方法;它)。它在已经填充的数字上加了0.001,所以它在十进制值的右边加了1 3 # eyz1。所以使用起来应该是安全的。

之后,我添加了.toFixed(decimal),以始终以正确的格式输出数字(具有正确数量的小数)。

差不多就是这样了。好好使用它;)

编辑:增加功能的“纠正”;负数。

浮点值的问题在于,它们试图用固定数量的比特表示无限数量的(连续的)值。所以自然地,在游戏中一定会有一些损失,你会被一些价值观咬伤。

当计算机将1.275存储为浮点值时,它实际上不会记住它是1.275还是1.27499999999999993,甚至是1.27500000000000002。这些值在四舍五入到两个小数后应该会给出不同的结果,但它们不会,因为对于计算机来说,它们在存储为浮点值后看起来是完全一样,并且没有办法恢复丢失的数据。任何进一步的计算只会积累这样的不精确性。

因此,如果精度很重要,就必须从一开始就避免使用浮点值。最简单的选择是

  • 使用专门图书馆
  • 使用字符串存储和传递值(附带字符串操作)
  • 使用整数(例如,你可以传递实际值的百分之一,例如,用美分代替美元)

例如,当使用整数存储百分位数时,查找实际值的函数非常简单:

function descale(num, decimals) {
var hasMinus = num < 0;
var numString = Math.abs(num).toString();
var precedingZeroes = '';
for (var i = numString.length; i <= decimals; i++) {
precedingZeroes += '0';
}
numString = precedingZeroes + numString;
return (hasMinus ? '-' : '')
+ numString.substr(0, numString.length-decimals)
+ '.'
+ numString.substr(numString.length-decimals);
}


alert(descale(127, 2));

对于字符串,你需要四舍五入,但它仍然是可控的:

function precise_round(num, decimals) {
var parts = num.split('.');
var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
var decimalPart = parts.length > 1 ? parts[1] : '';
if (decimalPart.length > decimals) {
var roundOffNumber = decimalPart.charAt(decimals);
decimalPart = decimalPart.substr(0, decimals);
if ('56789'.indexOf(roundOffNumber) > -1) {
var numbers = integralPart + decimalPart;
var i = numbers.length;
var trailingZeroes = '';
var justOneAndTrailingZeroes = true;
do {
i--;
var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
if (roundedNumber === '0') {
trailingZeroes += '0';
} else {
numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
justOneAndTrailingZeroes = false;
break;
}
} while (i > 0);
if (justOneAndTrailingZeroes) {
numbers = '1' + trailingZeroes;
}
integralPart = numbers.substr(0, numbers.length - decimals);
decimalPart = numbers.substr(numbers.length - decimals);
}
} else {
for (var i = decimalPart.length; i < decimals; i++) {
decimalPart += '0';
}
}
return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}


alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

注意,这个函数舍入到最近的距离为0,而IEEE 754建议舍入到最近的连偶作为浮点运算的默认行为。这样的修改留给读者练习:)

这里有一个简单的例子

function roundFloat(num,dec){
var d = 1;
for (var i=0; i<dec; i++){
d += "0";
}
return Math.round(num * d) / d;
}

比如使用alert(roundFloat(1.79209243929,4));

Jsfiddle

有一种方法可以100%确定你得到的数字有两个小数:

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

如果这会导致舍入误差,你可以使用James在他的评论中解释的以下方法:

(Math.round((num * 1000)/10)/100).toFixed(2)

这是一个老话题,但仍然排名靠前的谷歌结果和提供的解决方案共享相同的浮点小数问题。下面是我使用的(非常通用的)函数感谢MDN:

function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);


value = +value;
exp = +exp;


if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;


// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));


// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

正如我们所看到的,我们没有得到这些问题:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

这个泛型还提供了一些很酷的东西:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

现在,要回答OP的问题,你必须输入:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

或者,对于一个更简洁,不那么通用的函数:

function round2Fixed(value) {
value = +value;


if (isNaN(value))
return NaN;


// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));


// Shift back
value = value.toString().split('e');
return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

你可以用:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

各种例子和测试(感谢< >强@t-j-crowder < / >强!):

function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);


value = +value;
exp = +exp;


if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;


// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));


// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
function naive(value, exp) {
if (!exp) {
return Math.round(value);
}
var pow = Math.pow(10, exp);
return Math.round(value * pow) / pow;
}
function test(val, places) {
subtest(val, places);
val = typeof val === "string" ? "-" + val : -val;
subtest(val, places);
}
function subtest(val, places) {
var placesOrZero = places || 0;
var naiveResult = naive(val, places);
var roundResult = round(val, places);
if (placesOrZero >= 0) {
naiveResult = naiveResult.toFixed(placesOrZero);
roundResult = roundResult.toFixed(placesOrZero);
} else {
naiveResult = naiveResult.toString();
roundResult = roundResult.toString();
}
$("<tr>")
.append($("<td>").text(JSON.stringify(val)))
.append($("<td>").text(placesOrZero))
.append($("<td>").text(naiveResult))
.append($("<td>").text(roundResult))
.appendTo("#results");
}
test(0.565, 2);
test(0.575, 2);
test(0.585, 2);
test(1.275, 2);
test(1.27499, 2);
test(1234.5678, -2);
test(1.2345678e+2, 2);
test("123.45");
test(10.8034, 2);
test(10.8, 2);
test(1.005, 2);
test(1.0005, 2);
table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid #ddd;
}
td, th {
padding: 4px;
}
th {
font-weight: normal;
font-family: sans-serif;
}
td {
font-family: monospace;
}
<table>
<thead>
<tr>
<th>Input</th>
<th>Places</th>
<th>Naive</th>
<th>Thorough</th>
</tr>
</thead>
<tbody id="results">
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

以下置于全局范围:

Number.prototype.getDecimals = function ( decDigCount ) {
return this.toFixed(decDigCount);
}

和# EYZ0:

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

更新

请注意,toFixed()只能用于0-20之间的小数,即a.getDecimals(25)可能会生成一个javascript错误,所以为了适应,你可以添加一些额外的检查,即。

Number.prototype.getDecimals = function ( decDigCount ) {
return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}

四舍五入您的十进制值,然后使用toFixed(x)作为您期望的数字。

function parseDecimalRoundAndFixed(num,dec){
var d =  Math.pow(10,dec);
return (Math.round(num * d) / d).toFixed(dec);
}

调用

parseDecimalRoundAndFixed(10.800243929,4) => 10.80 parseDecimalRoundAndFixed(10.807243929,2) => 10.81

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

这个对我来说很管用:四舍五入小数在JavaScript

(Math.round((10.2)*100)/100).toFixed(2)

结果应该是:10.20

(Math.round((.05)*100)/100).toFixed(2)

结果应该是:0.05

(Math.round((4.04)*100)/100).toFixed(2)

结果应该是:4.04

等。

我正在修复修饰语的问题。 # EYZ0 < / >强

.
$(function(){
//input number only.
convertNumberFloatZero(22); // output : 22.00
convertNumberFloatZero(22.5); // output : 22.50
convertNumberFloatZero(22.55); // output : 22.55
convertNumberFloatZero(22.556); // output : 22.56
convertNumberFloatZero(22.555); // output : 22.55
convertNumberFloatZero(22.5541); // output : 22.54
convertNumberFloatZero(22222.5541); // output : 22,222.54


function convertNumberFloatZero(number){
if(!$.isNumeric(number)){
return 'NaN';
}
var numberFloat = number.toFixed(3);
var splitNumber = numberFloat.split(".");
var cNumberFloat = number.toFixed(2);
var cNsplitNumber = cNumberFloat.split(".");
var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
if(lastChar > 0 && lastChar < 5){
cNsplitNumber[1]--;
}
return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Number(((Math.random() * 100) + 1).toFixed(2))

这将返回一个从1到100四舍五入到小数点后2位的随机数。

.
/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/


var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));


/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/


if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");


/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

这很简单,和其他方法一样有效:

function parseNumber(val, decimalPlaces) {
if (decimalPlaces == null) decimalPlaces = 0
var ret = Number(val).toFixed(decimalPlaces)
return Number(ret)
}

由于toFixed()只能在数字上调用,并且不幸地返回一个字符串,因此它在两个方向上为您完成所有解析。你可以传递一个字符串或一个数字,每次你都会得到一个数字!调用parseNumber(1.49)将返回1,而调用parseNumber(1.49,2)将返回1.50。就像他们中最好的一样!

您还可以使用.toPrecision()方法和一些自定义代码,无论int部分的长度如何,始终四舍五入到小数第n位。

function glbfrmt (number, decimals, seperator) {
return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

你也可以让它成为一个插件,以便更好地使用。

通过引用使用此响应:https://stackoverflow.com/a/21029698/454827

我建立了一个函数来获得动态的小数数:

function toDec(num, dec)
{
if(typeof dec=='undefined' || dec<0)
dec = 2;


var tmp = dec + 1;
for(var i=1; i<=tmp; i++)
num = num * 10;


num = num / 10;
num = Math.round(num);
for(var i=1; i<=dec; i++)
num = num / 10;


num = num.toFixed(dec);


return num;
}

这里的工作示例:https://jsfiddle.net/wpxLduLc/

parse = function (data) {
data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
if (data != null) {
var lastone = data.toString().split('').pop();
if (lastone != '.') {
data = parseFloat(data);
}
}
return data;
};


$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

100%的工作! !试一试

<html>
<head>
<script>
function replacePonto(){
var input = document.getElementById('qtd');
var ponto = input.value.split('.').length;
var slash = input.value.split('-').length;
if (ponto > 2)
input.value=input.value.substr(0,(input.value.length)-1);


if(slash > 2)
input.value=input.value.substr(0,(input.value.length)-1);


input.value=input.value.replace(/[^0-9.-]/,'');


if (ponto ==2)
input.value=input.value.substr(0,(input.value.indexOf('.')+3));


if(input.value == '.')
input.value = "";
}
</script>
</head>
<body>
<input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
</body>
</html>

一轮下来

function round_down(value, decPlaces) {
return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

围捕

function round_up(value, decPlaces) {
return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

圆的

function round_nearest(value, decPlaces) {
return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

合并https://stackoverflow.com/a/7641824/1889449和 # EYZ0谢谢 他们。< / p >

在这些例子中,当你试图四舍五入数字1.005时,你仍然会得到一个错误,解决方案是使用Math.js这样的库或这个函数:

function round(value: number, decimals: number) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

通常,十进制舍入是通过缩放:round(num * p) / p来完成的

天真的实现

使用下面带有中间数的函数,您将得到预期的上四舍五入值,或者有时根据输入得到下四舍五入值。

舍入中的inconsistency可能会在客户端代码中引入难以检测的错误。

function naiveRound(num, decimalPlaces) {
var p = Math.pow(10, decimalPlaces);
return Math.round(num * p) / p;
}


console.log( naiveRound(1.245, 2) );  // 1.25 correct (rounded as expected)
console.log( naiveRound(1.255, 2) );  // 1.25 incorrect (should be 1.26)

更好的实现

通过将数字转换为指数的符号中的字符串,正数按预期四舍五入。 但是,要注意,负数四舍五入与正数不同

事实上,它执行的基本等同于规则“round half up”;,你会看到round(-1.005, 2)的计算结果是-1,即使round(1.005, 2)的计算结果是1.01lodash _。圆法使用这种技术。

/**
* Round half up ('round half towards positive infinity')
* Uses exponential notation to avoid floating-point issues.
* Negative numbers round differently than positive numbers.
*/
function round(num, decimalPlaces) {
num = Math.round(num + "e" + decimalPlaces);
return Number(num + "e" + -decimalPlaces);
}


// test rounding of half
console.log( round(0.5, 0) );  // 1
console.log( round(-0.5, 0) ); // 0


// testing edge cases
console.log( round(1.005, 2) );   // 1.01
console.log( round(2.175, 2) );   // 2.18
console.log( round(5.015, 2) );   // 5.02


console.log( round(-1.005, 2) );  // -1
console.log( round(-2.175, 2) );  // -2.17
console.log( round(-5.015, 2) );  // -5.01

如果您希望在负数舍入时保持通常的行为,则需要在调用Math.round ()之前将负数转换为正数,然后在返回之前将它们转换回负数。

// Round half away from zero
function round(num, decimalPlaces) {
num = Math.round(Math.abs(num) + "e" + decimalPlaces) * Math.sign(num);
return Number(num + "e" + -decimalPlaces);
}

有一种不同的纯数学技术可以执行舍入到最近(使用“离零的半圆”;),其中在调用舍入函数之前应用ε校正

简单地说,我们添加最小的浮动值(= 1.0 ulp;单位在最后的位置)到数字之前舍入。这将移动到数字之后的下一个可表示的值,远离零。

/**
* Round half away from zero ('commercial' rounding)
* Uses correction to offset floating-point inaccuracies.
* Works symmetrically for positive and negative numbers.
*/
function round(num, decimalPlaces) {
var p = Math.pow(10, decimalPlaces);
var e = Number.EPSILON * num * p;
return Math.round((num * p) + e) / p;
}


// test rounding of half
console.log( round(0.5, 0) );  // 1
console.log( round(-0.5, 0) ); // -1


// testing edge cases
console.log( round(1.005, 2) );  // 1.01
console.log( round(2.175, 2) );  // 2.18
console.log( round(5.015, 2) );  // 5.02


console.log( round(-1.005, 2) ); // -1.01
console.log( round(-2.175, 2) ); // -2.18
console.log( round(-5.015, 2) ); // -5.02

这需要抵消在十进制数字编码期间可能出现的隐式舍入误差,特别是那些有"5"在小数点后的最后一位,比如1.005、2.675和16.235。实际上,十进制系统中的1.005编码为64位二进制浮点的1.0049999999999999;而十进制系统中的1234567.005被编码为64位二进制浮点的1234567.0049999998882413

值得注意的是,最大二进制数round-off error依赖于(1)数字的大小和(2)相对机器ε(2^-52)。

以下是我的解决方案:Number((yourNumericValueHere).toFixed(2));

事情是这样的:

1)首先,将.toFixed(2)应用到要四舍五入的小数上。注意,这将把值从number转换为字符串。所以如果你使用Typescript,它会抛出一个这样的错误:

" string类型不能赋值给number类型"

2)要返回数值或将字符串转换为数值,只需对所谓的“字符串”值应用Number()函数。

为了说明问题,请看下面的例子:

< >强的例子: 我有一个金额,有高达5位小数,我想缩短到2位小数。我这样做:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

我从几个月前的这篇文章中得到了一些想法,但这里的答案,以及其他文章/博客的答案都不能处理所有的场景(例如负数和我们的测试人员发现的一些“幸运数字”)。最后,我们的测试人员没有发现下面这个方法有任何问题。粘贴我的代码片段:

fixPrecision: function (value) {
var me = this,
nan = isNaN(value),
precision = me.decimalPrecision;


if (nan || !value) {
return nan ? '' : value;
} else if (!me.allowDecimals || precision <= 0) {
precision = 0;
}


//[1]
//return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
precision = precision || 0;
var negMultiplier = value < 0 ? -1 : 1;


//[2]
var numWithExp = parseFloat(value + "e" + precision);
var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
return parseFloat(roundedNum.toFixed(precision));
},

我也有代码注释(对不起,我已经忘记了所有的细节)…我把我的答案贴在这里,以供将来参考:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).

我发现了一个非常简单的方法来解决这个问题,可以使用或适应:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

下面是https://stackoverflow.com/a/21323330/916734的TypeScript实现。它还使用了函数,并允许可选的数字偏移量。

export function round(rawValue: number | string, precision = 0, fractionDigitOffset = 0): number | string {
const value = Number(rawValue);
if (isNaN(value)) return rawValue;


precision = Number(precision);
if (precision % 1 !== 0) return NaN;


let [ stringValue, exponent ] = scientificNotationToParts(value);


let shiftExponent = exponentForPrecision(exponent, precision, Shift.Right);
const enlargedValue = toScientificNotation(stringValue, shiftExponent);
const roundedValue = Math.round(enlargedValue);


[ stringValue, exponent ] = scientificNotationToParts(roundedValue);
const precisionWithOffset = precision + fractionDigitOffset;
shiftExponent = exponentForPrecision(exponent, precisionWithOffset, Shift.Left);


return toScientificNotation(stringValue, shiftExponent);
}


enum Shift {
Left = -1,
Right = 1,
}


function scientificNotationToParts(value: number): Array<string> {
const [ stringValue, exponent ] = value.toString().split('e');
return [ stringValue, exponent ];
}


function exponentForPrecision(exponent: string, precision: number, shift: Shift): number {
precision = shift * precision;
return exponent ? (Number(exponent) + precision) : precision;
}


function toScientificNotation(value: string, exponent: number): number {
return Number(`${value}e${exponent}`);
}

又快又简单

parseFloat(number.toFixed(2))

例子

let number = 2.55435930


let roundedString = number.toFixed(2)    // "2.55"


let twoDecimalsNumber = parseFloat(roundedString)    // 2.55


let directly = parseFloat(number.toFixed(2))    // 2.55

Christian C. Salvadó的回答 .的基础上,执行以下操作将输出一个Number类型,而且似乎也很好地处理了舍入:

const roundNumberToTwoDecimalPlaces = (num) => Number(new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(num));


roundNumberToTwoDecimalPlaces(1.344); // => 1.34
roundNumberToTwoDecimalPlaces(1.345); // => 1.35

上面提到的与前面提到的不同之处在于,在使用它[时不需要.format()链接,并且它输出一个Number类型]。