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


этот вопрос уже есть ответ здесь:

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

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

list.Count() / 10

или

list.Count() / (decimal)10

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

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

8 69

8 ответов:

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

(list.Count() + 9) / 10

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


вопрос ОП обобщает (принцип pigeonhole) to:

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

решение:

  1. выводится из осознания того, что последнее поле может быть частично пустым, и
  2. и (x + y - 1) ÷ 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

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

после аргумента о 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 alike 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);
    }   
}

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

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

вы можете использовать математику.Потолок

http://msdn.microsoft.com/en-us/library/system.math.ceiling%28v=VS.100%29.aspx

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

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

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

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

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

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

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

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

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

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

(list.Count()+9)/10