在Javascript中舍入负数

时间:2017-01-11 09:18:11

标签: javascript math rounding

我们在JavaScript中遇到了 Math.round()的问题。问题是这个函数没有正确地舍入负数。例如:

1.5~ = 2

0.5~ = 1

-0.5~ = 0 //错误

-1.5~ = -1 //错误

根据算术舍入,这是不正确的。 -0.5的正确数字应为-1,-1.5应为-2。

有没有标准方法,在Javascript中正确舍入负数?

7 个答案:

答案 0 :(得分:14)

转换为正数后应用Math.round,最后回滚符号。您可以使用Math.sign方法从数字中获取符号,并使用Math.abs获取数字的绝对值。

console.log(
  Math.sign(num) * Math.round(Math.sign(num) * num),
  // or
  Math.sign(num) * Math.round(Math.abs(num))
)

var nums = [-0.5, 1.5, 3, 3.6, -4.8, -1.3];

nums.forEach(function(num) {
  console.log(
    Math.sign(num) * Math.round(Math.sign(num) * num),
    Math.sign(num) * Math.round(Math.abs(num))
  )
});

答案 1 :(得分:5)

您可以在ES5中保存标志并稍后申请;

function round(v) {
    return (v >= 0 || -1) * Math.round(Math.abs(v));
}

console.log(round(1.5));  //  2
console.log(round(0.5));  //  1
console.log(round(-1.5)); // -2
console.log(round(-0.5)); // -1

答案 2 :(得分:1)

您可以尝试使用Math.ceil(num)舍入num,然后使用-1(如果num为负数),例如

if (num < 0) {
  num = Math.ceil(num) - 1;
} else {
  num = Math.ceil(num);
}

答案 3 :(得分:0)

image['data-src'] = 'foobar';

在不使用数学库的情况下纯粹评估结果如何?例如,通过使用三元运算符,您可以优雅地检查负数,然后在“四舍五入”后取整:

var r = (Math.random() * 200) - 100;

var n = r + (r < 0 ? -0.5 : 0.5) | 0; 只是js中的一个愚蠢技巧,它“过载”了二进制运算符(您可以使用任何二进制运算符)以截断数字。

请注意,这不是下标(例如| 0),因为例如Math.floor实际上会产生Math.floor(-3.2)


一个人甚至可以做类似于@Balan的回答(我喜欢下面的一个和一个,但是我觉得这样或三元运算符会更快一点-但是,我可能错了,因为{ {1}}库已被证明非常快):

-4

可能是最快,最优雅的方式:

Math

示例:

var n = (r + Math.sign(r) / 2) | 0;
var n = Math.floor(r + 0.5);
var body = document.getElementById("myTable").children[1];
var i, iMax = 100, r, tr, td;
for (i = 0; i < iMax; i++) {
    r = Math.random() * 200 - 100;
    tr = document.createElement("tr");
    td = document.createElement("td");
    td.innerHTML = r;
    tr.appendChild(td);
    td = document.createElement("td");
    td.innerHTML = (r + Math.sign(r) / 2) | 0;
    tr.appendChild(td);
    body.appendChild(tr);
}

答案 4 :(得分:0)

精确舍入。
默认情况下四舍五入为Int;如果提供第二个参数,则四舍五入为小数点后n位。
+'1'修复了.0X5数字的错误舍入。

function round(num, digits=0) {
    if (!(num % 1)) return num
    return +Number(num + '1').toFixed(digits)
}

答案 5 :(得分:0)

首先请注意,Math.round(v)被定义为Math.floor(v + 0.5)

Math.round(-1.7) === -2
Math.round(-1.3) === -1
Math.floor(-1.7 + 0.5) === -2
Math.floor(-1.3 + 0.5) === -1

然后认识到parseInt(v)Math.floor(v)类似,但是,它对负数的处理方式不同(确切地说,是您期望的行为方式):

Math.floor(1.7) === 1
Math.floor(-1.7) === -2
parseInt(1.7) === 1
parseInt(-1.7) === -1

因此,parseInt(v)行为是您想要的,但您希望舍入而不是下限。为了将其应用于任何数字,我们需要为正数添加+0.5,为负数添加-0.5。因此,解决方案是此功能

var parseIntRound = function(v)
{
    return parseInt(v + Math.sign(v)/2);
};
// or with modern syntactic sugar:
// const parseIntRound = v => parseInt(v + Math.sign(v)/2);

parseIntRound( 1.5) ===  2
parseIntRound( 0.5) ===  1
parseIntRound(-0.5) === -1
parseIntRound(-1.3) === -1
parseIntRound(-1.5) === -2
parseIntRound(-1.7) === -2

Math.sign(v)的任何正数(> 0)返回1,任何负数(<0)返回-1,正零返回0(负零返回-0)。

答案 6 :(得分:0)

ES6 添加了一个名为 Math.trunc 的方法,我们可以使用它来获取十进制数的整数部分

<块引用>

Math.trunc() 函数通过以下方式返回数字的整数部分 删除任何小数位。

Math.trunc(42.84) -> Returns 42
Math.trunc(5.3) -> Returns 5
Math.trunc(-4.3) -> Returns -4
Math.trunc(-3.123) -> Returns -3