Как всегда округлить до следующего целого числа

Я пытаюсь найти общие страницы при создании пейджера на веб-сайте (так что я хочу, чтобы результат был целым числом. Я получаю список записей, и я хочу разделить на 10 на страницу (количество страниц)

когда я делаю это:

list.Count() / 10

или

list.Count() / (decimal)10

и list.Count() =12, я получаю результат 1.

Как бы я закодировал его, поэтому я получаю 2 в этом случае (остаток должен всегда добавлять 1)

Ответ 1

Math.Ceiling((double)list.Count() / 10);

Ответ 2

(list.Count() + 9) / 10

Все остальное здесь либо чрезмерно, либо просто неправильно (за исключением bestsss 'answer, что является удивительным). Мы выполняем не накладные расходы на вызов функции (Math.Truncate(), Math.Ceiling() и т.д.), Когда достаточно простой математики.


Вопрос ОП обобщает (принцип пигментных отверстий):

Сколько ящиков необходимо хранить x, если только объекты y вписываются в каждый ящик?

Решение:

Вы вспомните из 3 класса rd что целочисленное деление - это то, что мы делаем, когда говорим 5 ÷ 2 = 2.

Деление с плавающей запятой - это когда мы говорим 5 ÷ 2 = 2.5, но мы не хотим этого.

Многие языки программирования поддерживают целочисленное деление. В языках, полученных из C, вы получаете его автоматически, когда вы делите типы int (short, int, long и т.д.). Остальная/дробная часть любой операции деления просто отбрасывается, таким образом:

5 / 2 == 2

Заменяя наш исходный вопрос на x = 5 и y = 2, имеем:

Сколько ящиков нужно хранить 5 объектов, если в каждый ящик помещается только 2 объекта?

Теперь ответ должен быть очевиден: 3 boxes - первые два блока содержат два объекта, а последний - один.

(x + y - 1) ÷ y =
(5 + 2 - 1) ÷ 2 =
6 ÷ 2 =
3

Итак, для исходного вопроса x = list.Count(), y = 10, который дает решение без дополнительных вызовов функций:

(list.Count() + 9) / 10

Ответ 3

Правильный ориентир или как может лежать число

Следуя аргументу о Math.ceil(value/10d) и (value+9)/10 я в итоге закодировал правильный не мертвый код, эталонный тест режима без интерпретации. Я говорил, что написание микропроцессорного теста - непростая задача. Код ниже иллюстрирует это:

00:21:40.109 starting up....
00:21:40.140 doubleCeil: 19444599
00:21:40.140 integerCeil: 19444599
00:21:40.140 warming up...
00:21:44.375 warmup doubleCeil: 194445990000
00:21:44.625 warmup integerCeil: 194445990000
00:22:27.437 exec doubleCeil: 1944459900000, elapsed: 42.806s
00:22:29.796 exec integerCeil: 1944459900000, elapsed: 2.363s

Тест находится на Java, так как я хорошо знаю, как Hotspot оптимизирует и обеспечивает справедливый результат. С такими результатами никакая статистика, шум или что-либо еще может испортить его.

Integer Ceil безумно намного быстрее.

Код

package t1;

import java.math.BigDecimal;

import java.util.Random;

public class Div {
    static int[] vals;

    static long doubleCeil(){
        int[] v= vals;
        long sum = 0;
        for (int i=0;i<v.length;i++){
            int value = v[i];
            sum+=Math.ceil(value/10d);
        }
        return sum;
    }

    static long integerCeil(){      
        int[] v= vals;
        long sum = 0;
        for (int i=0;i<v.length;i++){
            int value = v[i];
            sum+=(value+9)/10;
        }
        return sum;     
    }

    public static void main(String[] args) {
        vals = new  int[7000];
        Random r= new Random(77);
        for (int i = 0; i < vals.length; i++) {
            vals[i] = r.nextInt(55555);
        }
        log("starting up....");

        log("doubleCeil: %d", doubleCeil());
        log("integerCeil: %d", integerCeil());
        log("warming up...");       

        final int warmupCount = (int) 1e4;
        log("warmup doubleCeil: %d", execDoubleCeil(warmupCount));
        log("warmup integerCeil: %d", execIntegerCeil(warmupCount));

        final int execCount = (int) 1e5;

        {       
        long time = System.nanoTime();
        long s = execDoubleCeil(execCount);
        long elapsed = System.nanoTime() - time;
        log("exec doubleCeil: %d, elapsed: %.3fs",  s, BigDecimal.valueOf(elapsed, 9));
        }

        {
        long time = System.nanoTime();
        long s = execIntegerCeil(execCount);
        long elapsed = System.nanoTime() - time;
        log("exec integerCeil: %d, elapsed: %.3fs",  s, BigDecimal.valueOf(elapsed, 9));            
        }
    }

    static long execDoubleCeil(int count){
        long sum = 0;
        for(int i=0;i<count;i++){
            sum+=doubleCeil();
        }
        return sum;
    }


    static long execIntegerCeil(int count){
        long sum = 0;
        for(int i=0;i<count;i++){
            sum+=integerCeil();
        }
        return sum;
    }

    static void log(String msg, Object... params){
        String s = params.length>0?String.format(msg, params):msg;
        System.out.printf("%tH:%<tM:%<tS.%<tL %s%n", new Long(System.currentTimeMillis()), s);
    }   
}

Ответ 4

Это также будет работать:

c = (count - 1) / 10 + 1;

Ответ 6

Я думаю, что самый простой способ - разделить два целых числа и увеличить на единицу:

int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);

Нет необходимости в библиотеках или функциях.

отредактирован с правильным кодом.

Ответ 7

Проверить с помощью mod - если есть остаток, просто увеличьте значение на единицу.

Ответ 8

Xform удваивает (и обратно) для простого потолка?

list.Count()/10 + (list.Count()%10 >0?1:0) - это плохо, div + mod

edit 1-й: на 2n думали, что, вероятно, быстрее (зависит от оптимизации): div * mul (mul быстрее, чем div и mod)

int c=list.Count()/10;
if (c*10<list.Count()) c++;

edit2. забыл самый естественный (добавление 9 обеспечивает округление для целых чисел)

(list.Count()+9)/10