как всегда округлить до следующего целого числа [дубликат]
этот вопрос уже есть ответ здесь:
Я пытаюсь найти общее количество страниц в здании пейджер на сайт (поэтому я хочу, чтобы результат был целым числом. я получаю список записей и я хочу разделить на 10 за страницу (страницу граф)
когда я делаю это:
list.Count() / 10
или
list.Count() / (decimal)10
и list.Count() =12
, Я получаю результат 1
.
как бы я закодировал его, чтобы я получил 2
в этом случае (остаток всегда должны добавить 1
)
8 ответов:
(list.Count() + 9) / 10
все остальное здесь либо излишне, либо просто неправильно (за исключением ответ bestsss, который является удивительным). Мы делаем не хочу, чтобы накладные расходы на вызов функции (
Math.Truncate()
,Math.Ceiling()
и т. д.) когда достаточно простой математики.
вопрос ОП обобщает (принцип pigeonhole) to:
сколько коробок мне нужно хранить
x
объекты, если толькоy
объекты помещаются в каждую коробку?решение:
- выводится из осознания того, что последнее поле может быть частично пустым, и
- и
(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); } }
вы можете использовать математику.Потолок
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);
нет необходимости в библиотеках или функциях.
отредактировано с помощью правильного кода.
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