如何总是四舍五入到下一个整数

我试图找到总页面在建立一个网站寻呼机(所以我希望的结果是一个整数。我得到一个记录列表,我想分为10页(页面计数)

当我这么做的时候:

list.Count() / 10

或者

list.Count() / (decimal)10

还有 list.Count() =12我得到了 1的结果。

在这种情况下,我如何编写代码以得到 2(其余部分应该总是添加 1)

169095 次浏览
Math.Ceiling((double)list.Count() / 10);

Check by using mod - if there is a remainder, simply increment the value by one.

Xform to double (and back) for a simple ceil?

list.Count()/10 + (list.Count()%10 >0?1:0) - this bad, div + mod

edit 1st: on a 2n thought that's probably faster (depends on the optimization): div * mul (mul is faster than div and mod)

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

edit2 scarpe all. forgot the most natural (adding 9 ensures rounding up for integers)

(list.Count()+9)/10

I think the easiest way is to divide two integers and increase by one :

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

No need of libraries or functions.

edited with the right code.

(list.Count() + 9) / 10

Everything else here is either overkill or simply wrong (except for bestsss' answer, which is awesome). We do not want the overhead of a function call (Math.Truncate(), Math.Ceiling(), etc.) when simple math is enough.


OP's question generalizes (pigeonhole principle) to:

How many boxes do I need to store x objects if only y objects fit into each box?

The solution:

  1. derives from the realization that the last box might be partially empty, and
  2. is (x + y - 1) ÷ y using integer division.

You'll recall from 3rd grade math that integer division is what we're doing when we say 5 ÷ 2 = 2.

Floating-point division is when we say 5 ÷ 2 = 2.5, but we don't want that here.

Many programming languages support integer division. In languages derived from C, you get it automatically when you divide int types (short, int, long, etc.). The remainder/fractional part of any division operation is simply dropped, thus:

5 / 2 == 2

Replacing our original question with x = 5 and y = 2 we have:

How many boxes do I need to store 5 objects if only 2 objects fit into each box?

The answer should now be obvious: 3 boxes -- the first two boxes hold two objects each and the last box holds one.

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

So for the original question, x = list.Count(), y = 10, which gives the solution using no additional function calls:

(list.Count() + 9) / 10

This will also work:

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

A proper benchmark or how the number may lie

Following the argument about Math.ceil(value/10d) and (value+9)/10 I ended up coding a proper non-dead code, non-interpret mode benchmark. I've been telling that writing micro benchmark is not an easy task. The code below illustrates this:

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

The benchmark is in Java since I know well how Hotspot optimizes and ensures it's a fair result. With such results, no statistics, noise or anything can taint it.

Integer ceil is insanely much faster.

The code

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);
}
}