Warum gibt Math.ceil ein Double zurück?

75

Wenn ich anrufe, ist Math.ceil(5.2)die Rückgabe die double 6.0. Meine natürliche Neigung war zu denken, dass a zurückkehren Math.ceil(double a)würde long. Aus der Dokumentation:

ceil(double a)

Gibt den kleinsten doubleWert (der der negativen Unendlichkeit am nächsten kommt) zurück , der nicht kleiner als das Argument ist und einer mathematischen Ganzzahl entspricht.

Aber warum doubleeher a als a zurückgeben, longwenn das Ergebnis eine ganze Zahl ist? Ich denke, das Verständnis des Grundes könnte mir helfen, Java ein bisschen besser zu verstehen. Es könnte mir auch helfen herauszufinden, ob ich mich selbst in Schwierigkeiten bringen werde, indem ich auf ein longz

long b = (long)Math.ceil(a);

immer was ich denke es sollte sein? Ich befürchte, es könnte einige Grenzfälle geben, die problematisch sind.

PengOne
quelle

Antworten:

70

Der Bereich von doubleist größer als der von long. Zum Beispiel:

double x = Long.MAX_VALUE;
x = x * 1000;
x = Math.ceil(x);

Was würden Sie von der letzten Zeile erwarten, wenn sie Math.ceilzurückgegeben wird long?

Beachten Sie, dass bei sehr großen Werten (positiv oder negativ) die Zahlen sehr spärlich verteilt sind. Die nächste Ganzzahl, die größer als die Ganzzahl xist, ist also nicht, x + 1wenn Sie sehen, was ich meine.

Jon Skeet
quelle
Ich denke, in Ihrem letzten Satz sprechen Sie von einem Verlust an Präzision, aber ich denke, das hängt nicht von der Höhe der Zahl ab, sondern von der Anzahl der signifikanten Stellen (in Binärform). Ich werde versuchen, ein Beispiel zu finden.
Aalku
@ user270349: Die absolute Lücke zwischen aufeinanderfolgenden Doppelwerten wird größer, wenn der Wert größer wird. Die Anzahl der dargestellten signifikanten Stellen bleibt gleich (außer bei subnormalen Zahlen).
Jon Skeet
2
Beispiel: 2^60kann als doppelt dargestellt werden, während 2^60 (+/-) 1nicht
aalku
Du hast recht. Ein Inkrement von eins in der Mantisse impliziert eine viel größere Zahl, wenn der Exponent groß und offensichtlich ist.
Aalku
6
Aber warum kommt dann rounda zurück long?
Zoltán
14

Ein Double kann größer sein als Long.MAX_VALUE. Wenn Sie einen Math.ceil()solchen Wert aufrufen, erwarten Sie, dass Sie denselben Wert zurückgeben. Wenn es jedoch einen langen Wert zurückgibt, ist der Wert falsch.

Peter Lawrey
quelle
Die doubleWerte, die größer als sind, werden Long.MAX_VALUEmöglicherweise nicht genau dargestellt, sodass das doubleErgebnis von ceil(big_double)nicht angezeigt wird big_double + 1. Also ist es immer noch falsch ...
Ciprian Tomoiagă
@CiprianTomoiaga Sie haben Recht, dass es nicht big_double +1 sein wird, da dies big_double wäre. Jeder Wert, der zu groß ist, um als a dargestellt zu werden, longhat keinen Bruchteil.
Peter Lawrey