在JavaScript中格式化一个正好两位小数的数字

Abs*_*Abs 557 javascript decimal-point rounding

我有这行代码将我的数字四舍五入到小数点后两位.但是我得到这样的数字:10.8,2.4等.这些不是我的两位小数的想法,所以我如何改进以下内容?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);
Run Code Online (Sandbox Code Playgroud)

我想要10.80,2.40等数字.使用jQuery对我很好.

CMS*_*CMS 962

要使用定点表示法格式化数字,只需使用toFixed方法:

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

var num = 2.4;
alert(num.toFixed(2)); // "2.40"
Run Code Online (Sandbox Code Playgroud)

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

重要提示:请注意,toFixed实际上并不实际上是圆形的,90%的时间它会返回舍入值,但在很多情况下它实际上并不起作用.在你的控制台中尝试这个:

2.005.toFixed(2)

你会得到错误的答案

在javascript中没有自然的方法来获得十进制舍入,您将需要自己的polyfill或使用库.你可以看看mozilla的polyfill这个https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round

  • 在这里必须同意@AshBlue ...这对于格式化值的表示是安全的.可能会因进一步计算而中断代码 否则`Math.round(value*100)/ 100`对于2DP更好. (78认同)
  • 固定不圆,你可以先做:(Math.round(0.09)).toFixed(1); (41认同)
  • @rekans:这是错的.`Math.Round(0.09)`将返回`0`所以这将总是给'0.0` ... (32认同)
  • 在大多数情况下,这是一个坏主意,在某些情况下,它会将数字转换为字符串或浮点数. (27认同)
  • 在所有浏览器中都不能一致地工作,即`(0.09).toFixed(1);`在IE8中给出0.0 (17认同)
  • 还是坏主意(Math.round(1.275*100)/ 100).toFixed(2)是1.27而不是1.28 (6认同)
  • 另外toFixed做圆.在firefox和IE`(0.19)中,.toFixed(1)`得到的结果为"0.2" (3认同)
  • 我要保留的一件事是,在讨论准确性时,`.ofFixed`并不总是可靠的.例如,`1.345.toFixed(2)`产生的结果为"1.34"`这是不正确的.更好的方法是使用`Math.round(1.345*100)/ 100 // 1.35`. (2认同)

ast*_*ije 96

这是一个古老的主题,但仍然排名靠前的谷歌搜索结果和所提供的解决方案共享相同的浮点小数问题.这是我使用的(非常通用的)函数,感谢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));
}
Run Code Online (Sandbox Code Playgroud)

我们可以看到,我们没有遇到这些问题:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27
Run Code Online (Sandbox Code Playgroud)

这种通用性也提供了一些很酷的东西:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123
Run Code Online (Sandbox Code Playgroud)

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

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"
Run Code Online (Sandbox Code Playgroud)

或者,为了更简洁,更通用的功能:

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);
}
Run Code Online (Sandbox Code Playgroud)

你可以用以下方式调用它:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"
Run Code Online (Sandbox Code Playgroud)

各种示例和测试(感谢@ tj-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);
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 怎么没有一个简单的方法来做到这一点?ES6 来拯救? (2认同)

Mig*_*uel 41

我通常将它添加到我的个人库中,经过一些建议并使用@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);
}
Run Code Online (Sandbox Code Playgroud)

将适用于所报告的例外情况.

  • 如果您的第二个函数被拾取,那么您在哪里声明"sign"和"dec"它是否应该将它们视为未定义? (6认同)
  • precise_round(1.275,2)是1.27? (2认同)
  • @Imre将返回值更改为(Math.round(num*Math.pow(10,decimals))/ Math.pow(10,decimals)).toFixed(2); 你将不再有这个问题. (2认同)
  • 我在IE中为missign sign方法添加了一个workarround:https://gist.github.com/ArminVieweg/28647e735aa6efaba401 (2认同)

小智 23

快速又简单

parseFloat(number.toFixed(2))
Run Code Online (Sandbox Code Playgroud)

例子

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
Run Code Online (Sandbox Code Playgroud)

  • 经过一段时间的搜索,终于这对我有用,简单又容易 (2认同)

tfr*_*oli 17

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

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}
Run Code Online (Sandbox Code Playgroud)

它的两条评论(来自@bostostkim和@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);
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我不得不添加一些"修正"(它不是它的原因,但由于Math.round是有损的 - 你可以在jsfiddle.net上查看它 - 这是我知道如何"修复"的唯一方法"它).它增加了0.001到已经填充的数量,所以它增加了13 0s到十进制值的权利.所以它应该是安全的.

之后我添加.toFixed(decimal)到始终以正确的格式输出数字(使用正确的小数).

所以这就是它.好好用;)

编辑:为负数的"修正"增加了功能.

  • "校正"*大多数是*安全的,但是例如`precise_round(1.27499,2)`现在也返回1.28 ......这不是有限的"Math.round"; 计算机内部存储浮点值的方式是.基本上,在数据进入函数之前,你注定要失败一些值:) (2认同)

Ger*_*ser 15

一种方法是100%确定你得到一个2位小数:

(Math.round(num*100)/100).toFixed(2)
Run Code Online (Sandbox Code Playgroud)

如果这导致舍入错误,您可以使用以下内容,正如詹姆斯在他的评论中解释的那样:

(Math.round((num * 1000)/10)/100).toFixed(2)
Run Code Online (Sandbox Code Playgroud)

  • 这是最好,最简单的方法.但是,由于浮点数学,1.275*100 = 127.49999999999999,这可能会导致舍入中的小错误.为了解决这个问题,我们可以乘以1000除以10,得到(1.275*1000)/ 10 = 127.5.如下:`var answer =(Math.round((num*1000)/ 10)/ 100).toFixed(2);` (6认同)

Sye*_*med 12

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
Run Code Online (Sandbox Code Playgroud)

如果你想要数字固定使用

result = num.toFixed(2);
Run Code Online (Sandbox Code Playgroud)


小智 5

我找不到这个问题的准确解决方案,所以我创建了自己的:

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;
}
Run Code Online (Sandbox Code Playgroud)

例子:

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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.这是一个测试这个的小曲子:http://jsfiddle.net/lamarant/ySXuF/.我在返回它之前将toFixed()应用于值,它将正确数量的零附加到返回值的末尾. (2认同)