【发布时间】:2011-03-16 07:20:48
【问题描述】:
嘿,我将如何将一个数字四舍五入到最接近 3 的倍数?
即
25 would return 27
1 would return 3
0 would return 3
6 would return 6
谢谢
【问题讨论】:
-
0 会返回 3????为什么?
标签: javascript integer rounding
嘿,我将如何将一个数字四舍五入到最接近 3 的倍数?
即
25 would return 27
1 would return 3
0 would return 3
6 would return 6
谢谢
【问题讨论】:
标签: javascript integer rounding
if(n > 0)
return Math.ceil(n/3.0) * 3;
else if( n < 0)
return Math.floor(n/3.0) * 3;
else
return 3;
【讨论】:
{25:27,1:3,0:3,6:6}[x]。即使您忽略x=0 的情况,如果-3 明显小于-1,如何将-1 舍入到-3?所述问题的正确答案是Math.ceil(x/3)*3。
(n - n mod 3)+3
【讨论】:
你来了!
Number.prototype.roundTo = function(num) {
var resto = this%num;
if (resto <= (num/2)) {
return this-resto;
} else {
return this+num-resto;
}
}
例子:
y = 236.32;
x = y.roundTo(10);
// results in x = 240
y = 236.32;
x = y.roundTo(5);
// results in x = 235
【讨论】:
Number(1).roundTo(3) 返回 0。
if(x%3==0)
return x
else
return ((x/3|0)+1)*3
【讨论】:
x/3|0 与Math.floor(x/3) 相同,但慢了 27%。另外,如果x=-4,那么它输出0,这显然是不正确的,无论你如何定义舍入。
此函数将四舍五入到您提供的任何因子的最接近的倍数。 它不会将 0 或已经是倍数的数字四舍五入。
round_up = function(x,factor){ return x - (x%factor) + (x%factor>0 && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
0
round_up(6,3)
6
0 的行为不是您所要求的,但这种方式似乎更加一致和有用。但是,如果您确实想四舍五入,则以下函数将执行此操作:
round_up = function(x,factor){ return x - (x%factor) + ( (x%factor>0 || x==0) && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
3
round_up(6,3)
6
【讨论】:
我用伪代码回答这个问题,因为我主要使用 SystemVerilog 和 Vera (ASIC HDL) 进行编程。 % 表示模函数。
round_number_up_to_nearest_divisor = number + ((divisor - (number % divisor)) % divisor)
这在任何情况下都有效。
数字的模计算余数,从除数中减去该余数得到下一个除数倍数所需的数字,然后“魔术”发生了。您会认为拥有单模函数就足够了,但是在数字是除数的精确倍数的情况下,它会计算一个额外的倍数。即,24 将返回 27。附加模数通过添加 0 来防止这种情况。
【讨论】:
function roundUpMultiple(num,div) {return num+((div-(num%div))%div)}
n=-.1;d=3;n+(d-n%d)%d 返回 8.326672684688674e-17。此方法还可用于通过使d 为负数将数字向下(而不是向上)四舍五入为 d 的倍数,但随后会导致大于 0 但小于 1 的数字失去意义,所以d=-3;[-3,-1,-.1,0,.1,3].map(function(x){return x+(d-x%d)%d}) 返回[-3,-3,-3,0,-8.326672684688674e-17,3]。
简单地说:
3.0*Math.ceil(n/3.0)
?
【讨论】:
if (n === 0) return 3:P
3.0*Math.round(25/3.0) 返回 24 而不是 27。
ceil 更改为floor,使其始终向下舍入到最接近的倍数。 ceil 到 round 以四舍五入到最接近的倍数。
$(document).ready(function() {
var modulus = 3;
for (i=0; i < 21; i++) {
$("#results").append("<li>" + roundUp(i, modulus) + "</li>")
}
});
function roundUp(number, modulus) {
var remainder = number % modulus;
if (remainder == 0) {
return number;
} else {
return number + modulus - remainder;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Round up to nearest multiple of 3:
<ul id="results">
</ul>
【讨论】:
正如对已接受答案的评论中提到的那样,您可以使用它:
Math.ceil(x/3)*3
(即使x 为 0 时它不返回 3,因为这可能是 OP 的错误。)
在此之前发布的九个答案中(尚未删除或分数不低以至于并非对所有用户可见),只有 Dean Nicholson 的答案(除了丢失的问题意义)和beauburrier是正确的。接受的答案给出了负数的错误结果,并为 0 添加了一个例外,以解释 OP 可能犯的错误。另外两个答案将一个数字舍入到最接近的倍数,而不是总是向上舍入,另外一个给出负数的错误结果,还有三个甚至给出正数的错误结果。
【讨论】:
ceil() 的这个和另一个需要注意的一点是 Javascript 对 ceil 和非常小的十进制值的陌生性。请注意这些示例:Math.ceil(216.3/3)*3 = 219。Math.ceil(216.00000000000003/3)*3 = 219。Math.ceil(216.000000000000003/3)*3 = 216。一个额外的小数位会中断 ceil,因此您尝试获得最接近的 3 倍数。根据您的需要,您可以@ 987654327@第一。
以@Makram 的方法为基础,并结合@Adam 的后续cmets,我修改了原始的Math.prototype 示例,使其在以零为中心和无偏系统中都能准确地舍入负数:
Number.prototype.mround = function(_mult, _zero) {
var bias = _zero || false;
var base = Math.abs(this);
var mult = Math.abs(_mult);
if (bias == true) {
base = Math.round(base / mult) * _mult;
base = (this<0)?-base:base ;
} else {
base = Math.round(this / _mult) * _mult;
}
return parseFloat(base.toFixed(_mult.precision()));
}
Number.prototype.precision = function() {
if (!isFinite(this)) return 0;
var a = this, e = 1, p = 0;
while (Math.round(a * e) / e !== a) { a *= 10; p++; }
return p;
}
示例:
(-2).mround(3) 返回 -3;
(0).mround(3) 返回 0;
(2).mround(3) 返回 3;
(25.4).mround(3) 返回 24;
(15.12).mround(.1) 返回 15.1
【讨论】:
一个更通用的答案可能对解决更通用问题的人有所帮助:如果您想将数字四舍五入为分数的倍数,请考虑使用库。这是 GUI 中的一个有效用例,其中小数被输入到输入中,例如,您想将它们强制为 0.25、0.2、0.5 等的倍数。那么天真的方法不会让您走得太远:
function roundToStep(value, step) {
return Math.round(value / step) * step;
}
console.log(roundToStep(1.005, 0.01)); // 1, and should be 1.01
在尝试编写自己的函数并查找 npm 包数小时后,我决定 Decimal.js 立即完成工作。它甚至有一个 toNearest 方法可以做到这一点,您可以选择是向上、向下还是更接近的值(默认值)。
const Decimal = require("decimal.js")
function roundToStep (value, step) {
return new Decimal(value).toNearest(step).toNumber();
}
console.log(roundToStep(1.005, 0.01)); // 1.01
【讨论】:
使用余数运算符(模数):
(n - 1 - (n - 1) % 3) + 3
【讨论】: