Ответ 1
Math.Ceiling((double)list.Count() / 10);
Я пытаюсь найти общие страницы при создании пейджера на веб-сайте (так что я хочу, чтобы результат был целым числом. Я получаю список записей, и я хочу разделить на 10 на страницу (количество страниц)
когда я делаю это:
list.Count() / 10
или
list.Count() / (decimal)10
и list.Count() =12
, я получаю результат 1
.
Как бы я закодировал его, поэтому я получаю 2
в этом случае (остаток должен всегда добавлять 1
)
Math.Ceiling((double)list.Count() / 10);
(list.Count() + 9) / 10
Все остальное здесь либо чрезмерно, либо просто неправильно (за исключением bestsss 'answer, что является удивительным). Мы выполняем не накладные расходы на вызов функции (Math.Truncate()
, Math.Ceiling()
и т.д.), Когда достаточно простой математики.
Вопрос ОП обобщает (принцип пигментных отверстий):
Сколько ящиков необходимо хранить
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
Следуя аргументу о 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);
}
}
Это также будет работать:
c = (count - 1) / 10 + 1;
Вы можете использовать Math.Ceiling
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 удваивает (и обратно) для простого потолка?
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