如何舍入和格式化 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.2
而 2.00
变成 2
,你可以使用 String.prototype.replace()
with a RegExp:total.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
};
}
我有两个相乘的输入,我需要将结果向下舍入而不带尾随零。我尝试了几种不同的内置方法,例如 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.2
而 2.00
变成 2
,你可以使用 String.prototype.replace()
with a RegExp:total.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
};
}