Округление числа до ближайшего кратного 3 - PullRequest
33 голосов
/ 15 июля 2010

Хей, как мне округлить число до ближайшего кратного 3?

т.е.

Ответы [ 10 ]

66 голосов
/ 15 июля 2010
    if(n > 0)
        return Math.ceil(n/3.0) * 3;
    else if( n < 0)
        return Math.floor(n/3.0) * 3;
    else
        return 3;
20 голосов
/ 15 июля 2010

Вот, пожалуйста!

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
15 голосов
/ 25 февраля 2014

Просто:

3.0*Math.round(n/3.0)

?

11 голосов
/ 16 июня 2016

Как уже упоминалось в комментарии к принятому ответу, вы можете просто использовать это:

Math.ceil(x/3)*3

(Даже если он не возвращает 3, когда x равен 0, потому что это, вероятно, было ошибкой ОП.)

Из девяти ответов, опубликованных до этого (которые не были удалены или которые не имеют такого низкого балла, чтобы они были видны не всем пользователям), только ответы Дина Николсона (исключая проблему с потерей значение) и бобурье верны. Принятый ответ дает неверный результат для отрицательных чисел и добавляет исключение для 0, чтобы учесть, что, вероятно, было ошибкой ОП. Два других ответа округляют число до ближайшего кратного числа вместо постоянного округления, еще один дает неверный результат для отрицательных чисел, и еще три дают неправильный результат для положительных чисел.

9 голосов
/ 24 апреля 2013

Я отвечаю на это в psuedocode, так как я программирую в основном в SystemVerilog и Vera (ASIC HDL). % представляет функцию модуля.

round_number_up_to_nearest_divisor = number + ((divisor - (number % divisor)) % divisor)

Это работает в любом случае.

Модуль числа вычисляет остаток, вычитая, что из делителя получается число, необходимое для перехода к следующему кратному делителю, после чего возникает «магия». Вы могли бы подумать, что достаточно иметь единственную функцию модуля, но в случае, когда число является точным кратным делителю, оно вычисляет дополнительное кратное число. то есть, 24 вернул бы 27. Дополнительный модуль защищает от этого, добавляя 0.

6 голосов
/ 04 апреля 2012

Эта функция округляет до ближайшего кратного любого из указанных вами факторов.Он не будет округлять 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
2 голосов
/ 20 октября 2017

Опираясь на подход @ Макрама, я обнаружил, что оригинальный пример Math.prototype не точно округляет отрицательные числа. Вот слегка измененная функция, которая обрабатывает как положительные, так и отрицательные числа как в экземпляре, так и в нескольких значениях:

Number.prototype.mround = function(_mult) {

    var base = Math.abs(this);
    var mult = Math.abs(_mult);
    var mod = (base % mult);

    if (mod <= (mult / 2)) { 
        base -= mod;
    } else {
        base += (mult - mod);
    }

    return (this<0)?-base:base ;

}

Примеры: (-2) .mround (3) возвращает -3;
(0) .mround (3) возвращает 0;
(2) .mround (3) возвращает 3;
(25.4) .mround (3) возвращает 24;

2 голосов
/ 15 июля 2010

(n - n mod 3) + 3

0 голосов
/ 17 мая 2016

$(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 голосов
/ 15 июля 2010
if(x%3==0)
    return x
else
    return ((x/3|0)+1)*3
...