如何舍入和格式化 JavaScript 中没有尾随零的数字?

How to round and format a number in JavaScript without trailing zeros?

我有两个相乘的输入,我需要将结果向下舍入而不带尾随零。我尝试了几种不同的内置方法,例如 number.toFixed(2),但它们没有产生预期的结果。

可以通过在此处的第一个和第二个输入中键入数字 20 和 6 来重现此问题:

$(document).on("change", ".p-cell, .s-cell", () => {
    var val1 = $(".p-cell").val();
    var val2 = $(".s-cell").val();    
    var total = val1 / 100 * val2;
    
    $(".w-cell").val(total).trigger("input");
});
<input class="p-cell" type="text" value="0" />
<input class="s-cell" type="text" value="0" />
<input class="w-cell" type="text" value="0" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

如果要显示两位小数,可以使用Number.prototype.toFixed().toFixed(2)

const $pCell = $(".p-cell");
const $sCell = $(".s-cell");
const $wCell = $(".w-cell");

$(document).on('input', '.p-cel, .s-cell', () => {
  const val1 = $pCell.val() || 0;
  const val2 = $sCell.val() || 0;
  const total = (val1 / 100 * val2).toFixed(2);
    
  $wCell.val(total);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input class="p-cell" type="text" value="0" />
<input class="s-cell" type="text" value="0" />
<input class="w-cell" type="text" value="0" readonly />

另外,如果你想删除任意数量的尾随零,所以 1.20 变成 1.22.00 变成 2,你可以使用 String.prototype.replace() with a RegExptotal.replace(/\.?0+$/, '')

const $pCell = $(".p-cell");
const $sCell = $(".s-cell");
const $wCell = $(".w-cell");

$(document).on('input', '.p-cel, .s-cell', () => {
  const val1 = $pCell.val() || 0;
  const val2 = $sCell.val() || 0;
  const total = (val1 / 100 * val2).toFixed(2);
    
  $wCell.val(total.replace(/\.?0+$/, ''));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input class="p-cell" type="text" value="0" />
<input class="s-cell" type="text" value="0" />
<input class="w-cell" type="text" value="0" readonly />

您可以使用 Math.round 舍入而不带尾随零。在这里我给你一个窍门。

        $(document).on("change", ".p-cell, .s-cell", function () {
    var val1 = $(".p-cell").val();
    var val2 = $(".s-cell").val();
    var total = Math.round((val1/100 * val2)*100)/100;
    $(".w-cell").val(total).trigger("input");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="p-cell" type="text" value="0" />
    <input class="s-cell" type="text" value="0" />
    <input class="w-cell" type="text" value="0" />

在JavaScript中有几种常见的方法可以四舍五入到固定的小数位数。每个都有一定的问题。

Number.protototype.toFixed方法

Number(x).toFixed(digits)

此方法生成具有请求位数的字符串。但是,它会在大约 9% 的时间内错误地舍入以 5 结尾的数字。

先乘后除法

Math.round( x * (10 ** digits) ) / (10 ** digits);

这会生成一个四舍五入为 digits 的数字,但大约有 0.7% 的时间四舍五入不正确。

指数加减法

Math.round( x + 'e' + digits ) + 'e-' + digits;

这会生成一个四舍五入为 digits 的数字,并且四舍五入正确。但它有一个致命的缺陷——对于小于1e-6的输入值,它returns NaN.

我编写了一个使用指数加减法的函数,但它避免了小输入值的致命错误。在 github.

可用
/**
 * round number `x` to `digits` number of digits after decimal point
 */
function roundToFixed (val, digits = 0) {
  if (typeof val === 'number' && typeof digits === 'number'
    && Number.isInteger(digits) &&
    (digits === 0 || Math.sign(digits) === 1)) {
    const valF = numToFloat(val);
    const valFNew = numToFloat(
      Math.round(+(valF.mant + 'e' + (valF.exp + digits)))
    );
    return +(valFNew.mant + 'e' + (valFNew.exp - digits));
  }
  return NaN;
}

/**
 * convert number to Float object
 */
function numToFloat (val) {
  const [mant, exp] = Number(val)
    .toExponential()
    .split('e')
    .map(str => +str);
  return {
    mant,
    exp
  };
}