我们正在用 Javascript 构建一个表,其中 Handsontable 表示货币金额。我们为用户提供了以两位小数或不带小数位呈现金额的可能性(这是客户的要求)。然后我们发现这样的事情:
Column A Column B Column C = A + B
-------------------------------------------
-273.50 273.50 0 Two decimals
-273 274 0 No decimals
稍微调查一下,我们发现 Javascript 中的基本舍入函数 Math.round()
, works like this :
If the fractional portion is exactly 0.5, the argument is rounded to the next integer in the direction of +∞. Note that this differs from many languages'
round()
functions, which often round this case to the next integer away from zero, instead (giving a different result in the case of negative numbers with a fractional part of exactly 0.5).
由于我们处理的是货币金额,我们不关心小数点后第二位会发生什么,因此我们选择将 -0.0000001 添加到表中的任何负值。因此,当呈现具有两位小数或没有小数的值时,现在我们得到正确的结果,如 Math.round(-273.5000001)
= -274,和 Math.round(-273.4900001)
仍然是 -273。
尽管如此,我们还是想找到一个更好的解决方案来解决这个问题。那么实现这一目标的最好、最优雅的方法是什么(不需要修改原始数值)?请注意,我们没有直接调用 Math.round(x)
,我们只是告诉 Handsontable 用给定的小数位数格式化一个值。
最佳答案
只是关于如何实现所需行为的一些变体,使用或不使用 Math.round()
。以及这些功能有效的证明。
由您决定哪个版本适合您。
const round1 = v => v<0 ? Math.ceil(v - .5) : Math.floor(+v + .5);
const round2 = v => Math.trunc(+v + .5 * Math.sign(v));
const round3 = v => Math.sign(v) * Math.round(Math.abs(v));
const round4 = v => v<0 ? -Math.round(-v): Math.round(v);
const funcs = [Number, Math.round, round1, round2, round3, round4];
[
-273.50, -273.49, -273.51,
273.50, 273.49, 273.51
].forEach(value => console.log(
Object.fromEntries(funcs.map(fn => [fn.name, fn(value)]))
));
关于javascript - 在 Javascript 中从零开始舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43273096/