403 Stimmen

Wie rundet man das Ergebnis einer Integer-Division auf?

Ich denke insbesondere darüber nach, wie ich Paginierungssteuerelemente anzeigen soll, wenn ich eine Sprache wie C# oder Java verwende.

Wenn ich x Elemente habe, die ich in Abschnitten von y pro Seite anzeigen möchte, wie viele Seiten werden benötigt?

1 Stimmen

Fehlt mir etwas? y/x + 1 funktioniert gut (vorausgesetzt, Sie wissen, dass der /-Operator immer abrundet).

69 Stimmen

@ rikkit - wenn y und x gleich sind, ist y/x + 1 auch eins zu hoch.

1 Stimmen

Für alle, die dies gerade erst entdecken, antwortet diese Antwort auf eine doppelte Frage überflüssige Konvertierungen in doppelte und vermeidet Überlaufprobleme, zusätzlich zu einer klaren Erklärung.

12voto

WIE MAN DAS ERGEBNIS DER GANZZAHLIGEN DIVISION IN C# AUFRUNDEN KANN

Mich interessierte, wie man dies in C# am besten macht, da ich dies in einer Schleife fast 100.000 Mal machen muss. Lösungen, die von anderen mit Math gepostet wurden, stehen oben in den Antworten, aber bei Tests habe ich festgestellt, dass sie langsam sind. Jarod Elliott schlug eine bessere Taktik vor, indem er überprüfte, ob der Modulo etwas produziert.

int result = (int1 / int2);
if (int1 % int2 != 0) { result++; }

Ich habe dies in einer Schleife 1 Million Mal ausgeführt und es hat 8ms gedauert. Hier ist der Code mit Math:

int result = (int)Math.Ceiling((double)int1 / (double)int2);

Was in meinem Test mit 14ms auffiel, deutlich länger.

Hinweis: Die erste Methode kann bei der Arbeit mit negativen Zahlen versagen.

1 Stimmen

Ja, die Gleitkomma-Division ist ziemlich "schrecklich". :) Diese Wahrheit reicht bis zur Entstehung der ersten Gleitkomma-CPU's/FPU's zurück. Tatsächlich gehen viele Spieleentwickler und andere, die hohe Leistung verlangen, umständlich vor, um Ganzzahl-Mathematik verwenden zu können.

1 Stimmen

Ich gehe davon aus, dass es länger dauert, weil es sich um größere Datentypen handelt, mehr Ziffern zu verwalten sind.

0 Stimmen

Was passiert, wenn int1 -1 ist und int2 2 ist? Möchten Sie wirklich -0,5 auf 1,0 runden?

8voto

Nicholas Petersen Punkte 8418

Benötigen Sie eine Erweiterungsmethode:

    public static int DivideUp(this int dividend, int divisor)
    {
        return (dividend + (divisor - 1)) / divisor;
    }

Hier keine Überprüfungen (Überlauf, DivideByZero, usw.), fügen Sie diese hinzu, wenn Sie möchten. Übrigens könnten einfache Funktionen wie diese vom Compiler sowieso inline ausgeführt werden, also denke ich nicht, dass man sich darüber Gedanken machen muss. Prost.

P.S. Es könnte auch nützlich sein, sich dessen bewusst zu sein (es gibt den Rest aus):

    int remainder; 
    int result = Math.DivRem(dividend, divisor, out remainder);

1 Stimmen

Das ist inkorrekt. Zum Beispiel: DivideUp(4, -2) gibt 0 zurück (sollte -2 sein). Es ist nur korrekt für nicht-negative ganze Zahlen, was aus der Antwort oder aus der Funktionsschnittstelle nicht klar hervorgeht.

8 Stimmen

Thash, warum tun Sie nicht etwas Nützliches wie das kleine zusätzliche Überprüfen hinzufügen, dann wenn die Zahl negativ ist, anstatt meine Antwort abzustimmen und fälschlicherweise die pauschale Aussage zu treffen: "Dies ist inkorrekt", wenn es sich tatsächlich nur um einen Randfall handelt. Ich habe bereits klargestellt, dass Sie zuerst andere Überprüfungen durchführen sollten: "Keine Überprüfungen hier (Überlauf, Durchnullteilen usw.), fühlen Sie sich frei, hinzuzufügen, wenn Sie möchten."

2 Stimmen

Die Frage erwähnte "Ich denke insbesondere darüber nach, wie man Paginierungssteuerelemente anzeigen kann", daher wären negative Zahlen sowieso außerhalb des Bereichs gewesen. Mach einfach etwas Nützliches und schlage eine zusätzliche Überprüfung vor, wenn du möchtest, es ist eine Teamarbeit, Mann.

8voto

finnw Punkte 46519

Eine Variante von Nick Berardis Antwort, die einen Zweig vermeidet:

int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));

Hinweis: (-r >> (Integer.SIZE - 1)) besteht aus dem Vorzeichenbit von r, das 32 Mal wiederholt wird (dank der Vorzeichenextension des >>-Operators.) Dies ergibt 0, wenn r null oder negativ ist, -1, wenn r positiv ist. Daher bewirkt das Subtrahieren von q den Effekt, dass 1 hinzugefügt wird, wenn records % recordsPerPage > 0.

4voto

Jarod Elliott Punkte 15024

Eine weitere Alternative besteht darin, die Funktion mod() (oder '%') zu verwenden. Wenn ein Restwert ungleich Null ist, wird das Ganzzahlergebnis der Division inkrementiert.

4voto

Mike Punkte 1167

Für records == 0 gibt rjmunros Lösung 1. Die korrekte Lösung ist 0. Trotzdem, wenn Sie wissen, dass records > 0 (und ich bin sicher, dass wir alle angenommen haben, dass recordsPerPage > 0), dann gibt rjmunro Lösung korrekte Ergebnisse und hat keine der Überlaufprobleme.

int pageCount = 0;
if (records > 0)
{
    pageCount = (((records - 1) / recordsPerPage) + 1);
}
// keine else notwendig

Alle mathematischen Integerlösungen werden effizienter sein als irgendeine der Lösungen mit Gleitkommazahlen.

0 Stimmen

Diese Methode wird wahrscheinlich kein Leistungsengpass sein. Und wenn doch, sollten Sie auch die Kosten des Zweigs berücksichtigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X