Antworten:
Sie 157/32
teilen zwei Ganzzahlen miteinander, was immer zu einer abgerundeten Ganzzahl führt. Deshalb (int) Math.ceil(...)
macht der nichts. Es gibt drei mögliche Lösungen, um das zu erreichen, was Sie wollen. Ich empfehle entweder Option 1 oder Option 2 . Bitte verwenden Sie NICHT verwenden Option 0 .
## Option 0
Konvertieren Sie a
und b
in ein Double, und Sie können die Division verwenden und Math.ceil
wie Sie wollten, dass es funktioniert. Ich rate jedoch dringend von der Verwendung dieses Ansatzes ab, da eine doppelte Teilung ungenau sein kann. Weitere Informationen zur Ungenauigkeit von Doppelbetten finden Sie in dieser Frage .
int n = (int) Math.ceil((double) a / b));
##Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
Sie tun a / b
immer Boden, wenn a
und b
beide ganze Zahlen sind. Dann haben Sie eine Inline-if-Anweisung, die prüft, ob Sie anstelle des Bodens eine Decke verwenden sollen oder nicht. Also +1 oder +0, wenn es einen Rest mit der Division gibt, brauchen Sie +1. a % b == 0
prüft auf den Rest.
##Option 2
Diese Option ist sehr kurz, aber für einige weniger intuitiv. Ich denke, dieser weniger intuitive Ansatz wäre schneller als der Ansatz der doppelten Teilung und des Vergleichs:
Bitte beachten Sie, dass dies nicht funktioniert b < 0
.
int n = (a + b - 1) / b;
Um die Wahrscheinlichkeit eines Überlaufs zu verringern, können Sie Folgendes verwenden. Bitte beachten Sie jedoch, dass es für a = 0
und nicht funktioniert b < 1
.
int n = (a - 1) / b + 1;
## Erklärung hinter dem "weniger intuitiven Ansatz"
Da das Teilen von zwei Ganzzahlen in Java (und den meisten anderen Programmiersprachen) immer das Ergebnis beeinflusst. So:
int a, b;
int result = a/b (is the same as floor(a/b) )
Aber wir wollen nicht floor(a/b)
, aber ceil(a/b)
und verwenden die Definitionen und Handlungen von Wikipedia :
Mit diesen Darstellungen der Boden- und Deckenfunktion können Sie die Beziehung sehen.
Sie können das sehen floor(x) <= ceil(x)
. Wir brauchen floor(x + s) = ceil(x)
. Also müssen wir finden s
. Wenn wir 1/2 <= s < 1
davon ausgehen, dass es genau richtig ist (probieren Sie einige Zahlen aus und Sie werden sehen, dass es so ist, ich finde es selbst schwierig, dies zu beweisen). Und 1/2 <= (b-1) / b < 1
so
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
Dies ist kein wirklicher Beweis, aber ich hoffe, Sie sind damit zufrieden. Wenn jemand es besser erklären kann, würde ich es auch schätzen. Vielleicht fragen Sie es bei MathOverflow .
157/32 ist int/int
, was zu einem führt int
.
Versuchen Sie es mit dem doppelten Literal - 157/32d
was bedeutet int/double
, dass a double
.
157/32
ist eine Ganzzahldivision, da alle numerischen Literale Ganzzahlen sind, sofern nicht anders mit einem Suffix angegeben ( d
für double l
for long).
Die Division wird abgerundet (auf 4), bevor sie in ein Double (4.0) umgewandelt wird, das dann aufgerundet wird (auf 4.0).
Wenn Sie Variablen verwenden, können Sie dies vermeiden
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Niemand hat das intuitivste erwähnt:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
Diese Lösung behebt die Ungenauigkeit der doppelten Teilung.
In Java wird durch Hinzufügen einer .0 ein doppeltes ...
int total = (int) Math.ceil(157.0 / 32.0);
Wenn zwei ganze Zahlen geteilt werden, z.
int c = (int) a / (int) b;
das Ergebnis ist ein int
, dessen Wert durch a
geteilt wird b
, gegen Null gerundet. Da das Ergebnis bereits gerundet ist, ceil()
wird nichts unternommen. Beachten Sie, dass diese Rundung nicht mit der Rundung in floor()
Richtung negativer Unendlichkeit identisch ist . Also, 3/2
gleich 1
(und floor(1.5)
gleich 1.0
, aber (-3)/2
gleich -1
(aber floor(-1.5)
gleich -2.0
).
Das ist wichtig , denn wenn a/b
waren immer gleich floor(a / (double) b)
, dann könnte man einfach implementieren ceil()
von a/b
wie -( (-a) / b)
.
Der Vorschlag, ceil(a/b)
von zu kommen
int n = (a + b - 1) / b;
, was äquivalent zu a / b + (b - 1) / b
oder ist(a - 1) / b + 1
funktioniert, weil ceil(a/b)
immer eins größer ist als floor(a/b)
, außer wenn a/b
eine ganze Zahl ist. Sie möchten es also auf die nächste ganze Zahl (oder darüber hinaus) stoßen, es sei denn, es a/b
handelt sich um eine ganze Zahl. Das Hinzufügen 1 - 1 / b
wird dies tun. Bei ganzen Zahlen werden sie nicht ganz auf die nächste ganze Zahl angehoben. Für alles andere wird es.
Huch. Hoffentlich macht das Sinn. Ich bin sicher, es gibt eine mathematisch elegantere Möglichkeit, dies zu erklären.
Um eine Zahl von einer Ganzzahl in eine reelle Zahl umzuwandeln, können Sie auch einen Punkt hinzufügen:
int total = (int) Math.ceil(157/32.);
Und das Ergebnis von (157/32.) Wird auch real sein. ;)
Java bietet /
standardmäßig nur eine Bodenteilung. Aber wir können die Decke in Bezug auf den Boden schreiben . Mal schauen:
y
Mit dem Formular kann eine beliebige Ganzzahl geschrieben werden y == q*k+r
. Nach der Definition der Bodenteilung (hier floor
), die abrundet r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
und der Deckenteilung (hier ceil
), die aufrundet r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
wo wir Ersatz r+1
für r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Dann setzen wir die erste Gleichung in die dritte ein, um zu q
erhalten
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Schließlich gegeben, jede ganze Zahl , y
wo y = q*k+r+1
für einige q
, k
, r
, wir haben
ceil(y, k) == floor(y-1, k) + 1
Und wir sind fertig. Hoffe das hilft.
ceil
als solches aus der intuitiven Definition definiert wird, insbesondere wenn wir die Obergrenze einer ganzen Zahl nehmen, dh r1 = k. Da die Randfälle das Knifflige daran sind, denke ich, dass es etwas genauer formuliert werden muss.
Es gibt zwei Methoden, mit denen Sie Ihren doppelten Wert aufrunden können.
Wenn Sie Ihre Antwort 4.90625 als 4 wünschen, sollten Sie Math.floor verwenden, und wenn Sie Ihre Antwort 4.90625 als 5 wünschen, können Sie Math.ceil verwenden
Sie können den folgenden Code dafür verwenden.
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
int total = (157-1)/32 + 1
oder allgemeiner
(a-1)/b +1