Хей, как бы я обошел округленное число до ближайшего кратного 3?
ie
25 would return 27
1 would return 3
0 would return 3
6 would return 6
спасибо
Хей, как бы я обошел округленное число до ближайшего кратного 3?
ie
25 would return 27
1 would return 3
0 would return 3
6 would return 6
спасибо
if(n > 0)
return Math.ceil(n/3.0) * 3;
else if( n < 0)
return Math.floor(n/3.0) * 3;
else
return 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
Просто:
3.0*Math.round(n/3.0)
?
Как упоминалось в комментарии к принятому ответу, вы можете просто использовать это:
Math.ceil(x/3)*3
(Даже если он не возвращает 3, когда x
равно 0, потому что это, вероятно, ошибка OP.)
Из девяти ответов, опубликованных до этого (которые не были удалены или у которых нет такой низкой оценки, что они не видны для всех пользователей), только те, которые Дин Николсон (за исключением проблемы с потерей значение) и beauburrier являются правильными. Принятый ответ дает неправильный результат для отрицательных чисел, и он добавляет исключение для 0, чтобы объяснить, что может быть ошибкой OP. Два других ответа вокруг числа до ближайшего множественного числа, а не округления, еще один дает неправильный результат для отрицательных чисел, а еще три дают неверный результат для положительных чисел.
Я отвечаю на это в psuedocode, так как я программирую в основном в SystemVerilog и Vera (ASIC HDL). % представляет собой функцию модуля.
round_number_up_to_nearest_divisor = number + ((divisor - (number % divisor)) % divisor)
Это работает в любом случае.
Модуль числа вычисляет остаток, вычитая, что из делителя получается число, необходимое для перехода к следующему делителю, затем происходит "волшебство". Вы могли бы подумать, что это достаточно хорошо, чтобы иметь единственную функцию модуля, но в случае, когда число является точным кратным дивизору, он вычисляет дополнительный кратный. т.е. 24 вернется 27. Дополнительный модуль защитит от этого, сделав добавление 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 - это не то, о чем вы просили, но кажется более последовательным и полезным таким образом. Если вы хотите округлить 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
(n - n mod 3) +3
Основываясь на подходе @Makram и включив последующие комментарии @Adam, я изменил исходный пример 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
$(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>
Более общий ответ, который может помочь кому-то с более общей проблемой: если вы хотите округлить числа до кратных дроби, подумайте об использовании библиотеки. Это допустимый вариант использования в графическом интерфейсе, где десятичные дроби вводятся во входные данные, и, например, вы хотите привести их к коэффициентам, кратным 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
if(x%3==0)
return x
else
return ((x/3|0)+1)*3