web-dev-qa-db-de.com

wie man immer auf die nächste ganze Zahl aufrundet

ich versuche, die Gesamtzahl der Seiten beim Erstellen eines Pagers auf einer Website zu ermitteln (daher möchte ich, dass das Ergebnis eine Ganzzahl ist. Ich erhalte eine Liste der Datensätze und möchte in 10 Seiten pro Seite aufteilen (die Anzahl der Seiten).

wenn ich das mache:

list.Count() / 10

oder

list.Count() / (decimal)10

und der list.Count() =12 erhalte ich ein Ergebnis von 1.

Wie würde ich es codieren, damit ich in diesem Fall 2 Erhalte (der Rest sollte immer 1 Hinzufügen)

78
leora
Math.Ceiling((double)list.Count() / 10);
164
Rob

(list.Count() + 9) / 10

Alles andere ist entweder übertrieben oder einfach falsch (mit Ausnahme von bestsss 'answer , was fantastisch ist). Wir wollen nicht den Overhead eines Funktionsaufrufs (Math.Truncate(), Math.Ceiling() usw.) wenn einfache Mathematik ausreicht.


Die Frage von OP verallgemeinert ( Pigeonhole-Prinzip ) auf:

Wie viele Boxen muss ich für die Speicherung von x Objekten verwenden, wenn nur y Objekte in jede Box passen?

Die Lösung:

  1. ergibt sich aus der Erkenntnis, dass das letzte Kästchen könnte teilweise leer ist, und
  2. ist (x + y - 1) ÷ y mit Integer Division .

Sie werden von 3 erinnernrd grade math that integer division machen wir, wenn wir sagen 5 ÷ 2 = 2.

Gleitkommadivision ist, wenn wir 5 ÷ 2 = 2.5 Sagen, aber wir nicht will das hier.

Viele Programmiersprachen unterstützen die Ganzzahlteilung. In Sprachen, die von C abgeleitet sind, erhalten Sie es automatisch, wenn Sie int -Typen (short, int, long usw.) teilen. Der Rest/Bruchteil einer Divisionsoperation wird einfach verworfen.

5 / 2 == 2

Wenn wir unsere ursprüngliche Frage durch x = 5 Und y = 2 Ersetzen, haben wir:

Wie viele Boxen brauche ich, um 5 Objekte zu speichern, wenn nur 2 Objekte in jede Box passen?

Die Antwort sollte jetzt offensichtlich sein: 3 boxes - Die ersten beiden Kästchen enthalten jeweils zwei Objekte und das letzte Kästchen enthält eines.

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

Also für die ursprüngliche Frage x = list.Count(), y = 10, Die die Lösung ohne zusätzliche Funktionsaufrufe gibt:

(list.Count() + 9) / 10

57
par

Ein richtiger Benchmark oder wie die Zahl liegen mag

Nach dem Argument über Math.ceil(value/10d) und (value+9)/10 Am Ende habe ich einen richtigen Benchmark für den nicht toten Code und den nicht interpretierbaren Modus codiert. Ich habe gesagt, dass das Schreiben eines Micro-Benchmarks keine leichte Aufgabe ist. Der folgende Code veranschaulicht dies:

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

Der Benchmark ist in Java da ich gut weiß, wie Hotspot optimiert und sicherstellt, dass es ein faires Ergebnis ist. Mit solchen Ergebnissen können keine Statistiken, Rauschen oder irgendetwas es beschmutzen.

Integer Ceil ist wahnsinnig viel schneller.

Der 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);
    }   
}
20
bestsss

Dies wird auch funktionieren:

c = (count - 1) / 10 + 1;
17
finnw
3
mfanto

Ich denke, der einfachste Weg ist, zwei ganze Zahlen zu teilen und um eine zu erhöhen:

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

Keine Bibliotheken oder Funktionen erforderlich.

bearbeitet mit dem richtigen Code.

3

Überprüfen Sie dies mit mod - wenn es einen Rest gibt, erhöhen Sie den Wert einfach um eins.

0
Den Delimarsky

Xform zu verdoppeln (und zurück) für eine einfache Decke?

list.Count()/10 + (list.Count()%10 >0?1:0) - dieser schlechte div + mod

edit 1 .: bei einem 2n gedanken ist das wahrscheinlich schneller (hängt von der optimierung ab): div * mul (mul ist schneller als div und mod)

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

edit2 Alles zerfleischen. vergaß das natürlichste (das Hinzufügen von 9 sorgt für eine Aufrundung für ganze Zahlen)

(list.Count()+9)/10

0
bestsss