私はウェブサイトでページャーを構築する際に合計ページを見つけようとしています(結果を整数にしたいです。レコードのリストを取得し、ページごとに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 を除く)。 not関数呼び出しのオーバーヘッドが必要(Math.Truncate()
、Math.Ceiling()
など)単純な数学で十分な場合。
OPの質問は、( ピジョンホールの原理 )を次のように一般化します:
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
に置き換えます:
各ボックスに2つのオブジェクトしか収まらない場合、5つのオブジェクトを格納するためにいくつのボックスが必要ですか?
答えは明らかです:3 boxes
-最初の2つのボックスにはそれぞれ2つのオブジェクトがあり、最後のボックスには1つのオブジェクトがあります。
(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
Hotspotがどのように最適化し、それが公正な結果であるかをよく知っているので、ベンチマークはJavaにあります。このような結果では、統計情報、ノイズなどは一切汚染できません。
整数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;
最も簡単な方法は、2つの整数を除算して1ずつ増やすことだと思います。
int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);
ライブラリや関数は必要ありません。
適切なコードで編集しました。
Modを使用して確認します-余りがある場合は、値を1つ増やします。
Xformをダブル(およびバック)にすると、単純な天井が得られますか?
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