2014-12-30 3 views
6

Die Frage ist ziemlich einfach, gibt es einen Nutzen oder einen Unterschied? Ich habe bemerkt, dass in C# die Funktion ein Doppel ohne Dezimalstellen zurückgibt, während in Java die Dezimalstellen beibehalten werden, ansonsten ist das Ergebnis dasselbe.Hat Math.Floor gegenüber dem expliziten Ganzzahl-Casting einen Vorteil?

Hier ist der Code, den ich in Java und C# verwendet wird, und die Ausgabe:

//Java          //C# 

double a = 5.5;        double a = 5.5; 
System.out.println(Math.floor(a));   Console.WriteLine(Math.Floor(a)); 
System.out.println((int)a);     Console.WriteLine((int)a); 

//Output          //Output 

5.0           5 
5            5 
+2

Java druckt '.0' auf alle Floats, denke ich. –

+0

Sie machen Annahme 'Java hält es' auf der Grundlage der Ausgabe von system.out? Es ist eine falsche Annahme –

+2

'Math.Floor' gibt ein Doppel ohne den Dezimalteil zurück. Es ist nicht das Gleiche wie Casting zu Integer –

Antwort

14

Ja, für negative Zahlen, das in der entgegengesetzten Art und Weise funktioniert.

Beispiel (mit Monos C# interaktiv Shell csharp):

csharp> Math.Floor(-12.0d) 
-12 
csharp> Math.Floor(-12.5d) 
-13 
csharp> (int) -12.5 
-12 

(für beide gleich Java/C#) und ich denke sowieso die meisten Sprachen.

Casting eine Fließkommazahl zu einer Ganzzahl, wird durch Wegwerfen des Dezimalteils unter Beibehaltung des ganzzahligen Teils ausgeführt. Der ganzzahlige Teil von -12.5 ist 12. So machen negative Zahlen eine Math.Ceil, wenn sie in eine int umgewandelt werden.

Weiterhin als @Matthew argumentiert, ein float oder double können Zahlen erreichen wie 1.023e23 (Avogadro-Konstante). Einfach weil die Mantisse Ziffern nicht mehr nach dem Komma darstellen kann. Zahlen, die sind betrachtet sowieso eine ganze Zahl, aber kann nicht durch eine int dargestellt werden. Durch Ausführen einer Operation Math.floor passiert nichts, aber der Wert wird weiterhin beibehalten.

Beispiel:

csharp> double ac = 1.023e23; 
csharp> Math.Floor(ac); 
1.023E+23 
csharp> (int) ac; 
0 

Hinweis: Während der Umwandlung in ein int in Überlauf führen könnte dies kann weit hergeholt aussehen, aber es ist also ein deutlicher Unterschied in der Semantik dennoch. Ein Unterschied, der ohnehin zu Fehlern führt.

Darüber hinaus ist es works differently für unendlich Zahlen und NaN:

System.out.println(Math.floor(Double.POSITIVE_INFINITY)); // Prints Infinity 
System.out.println((int)Double.POSITIVE_INFINITY);  // Prints 2147483647 
System.out.println(Math.floor(Double.NaN));    // Prints NaN 
System.out.println((int)Double.NaN);      // Prints 0 

Aber ich würde sie immer trotzdem verwenden. Casting macht die Dinge viel unlesbarer. Das Aufrunden/Abnehmen ist eher eine Art Nebeneffekt der Besetzung. Durch die Verwendung von Math.Ceil/Floor/Round ist klar, was du meinst.

Manchmal ist eine Umwandlung in eine ganze Zahl in der Tat ein wenig effizienter als eine Boden/Ceil-Operation zuerst durchzuführen. Aber ein intelligenter Compiler kann manchmal ableiten, dass eine Variable immer eine positive Zahl speichert und sie so selbst optimiert. Und darüber hinaus wird dies für die meisten Anwendungen zu einer unbedeutenden Leistungseinbuße führen.