Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [.NET] Math.Round() macht mich verrückt (https://www.delphipraxis.net/144626-%5B-net%5D-math-round-macht-mich-verrueckt.html)

Matze 12. Dez 2009 12:59


[.NET] Math.Round() macht mich verrückt
 
Hi zusammen,

.NET macht mich noch wahnsinnig. Gibt es keine saubere Möglichkeit, das hier zu schreiben?

Code:
intVal = Convert.ToInt32(Math.Round(Convert.ToDouble(tView.Height / 2)));
Da geht absolut jede Übersicht verloren.
Minimal schöner wäre es so:

Code:
intVal = Convert.ToInt32(Math.Round(tView.Height / 2));
Das ist jedoch nicht zulässig:

Zitat:

Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften: "System.Math.Round(decimal)" und "System.Math.Round(double)"
Geht's noch? :roll:

Erwartet hätte ich eine solche Lösung:

Code:
intVal = Math.Round(tView.Height / 2);
Dass Math.Round() beim Runden auf 0 Nachkommastellen einen Double-Wert zurück gibt ist doch irgendwo krank. :wall:

Mit einem Typecast ginge es kurz, doch ich persönlich finde Typecasts unsauber, da man nicht exakt weiß, was da nun wie interpretiert wird (Holzhammermethode):

Code:
intVal = (int)(tView.Height/ 2)

Grüße, Matze

Christian S. 12. Dez 2009 13:08

Re: [.NET] Math.Round() macht mich verrückt
 
Von welchem Typ ist tView.Height? Diese Fehlermeldung mit dem Decimal kann ich mir im Moment nämlich nicht erklären. :gruebel:

Generell finde ich es meist undurchsichtiger, was eine Convert-Funktion macht als was ein Cast macht. Dein Cast würde btw immer abrunden, oder?

Matze 12. Dez 2009 13:11

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Christian S.
Von welchem Typ ist tView.Height? Diese Fehlermeldung mit dem Decimal kann ich mir im Moment nämlich nicht erklären. :gruebel:

Das ist die Eigenschaft "Height" des TreeViews und somit ein Integer (int).

Zitat:

Zitat von Christian S.
Generell finde ich es meist undurchsichtiger, was eine Convert-Funktion macht als was ein Cast macht. Dein Cast würde btw immer abrunden, oder?

Hehe, du bist dir also auch nicht sicher, oder? Und genau darum mag ich Typecasts nicht.

Ich habe es lieber, wenn man exakt sehen kann, was mit den Werten passiert. Und das ist bei den Convert-Methoden der Fall.

Christian S. 12. Dez 2009 13:16

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Matze
Zitat:

Zitat von Christian S.
Generell finde ich es meist undurchsichtiger, was eine Convert-Funktion macht als was ein Cast macht. Dein Cast würde btw immer abrunden, oder?

Hehe, du bist dir also auch nicht sicher, oder?. Und genau darum mag ich Typecasts nicht.

Doch, ich bin mir sicher, aber wenn ein erfahrener Programmierer es anders benutzt, frage ich lieber nochmal nach. Ich kenne keine Sprache, in der ein Cast von Double nach Int runden würde.

Zitat:

Zitat von Matze
Ich habe es lieber, wenn man exakt sehen kann, was mit den Werten passiert. Und das ist bei den Convert-Methoden der Fall.

Naja, wenn ich mir die Beschreibung von Convert.Int32 durchlese ...

Zitat:

Return Value
value rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.
Als wirklich durchsichtig würde ich das nicht bezeichnen.

Lösung für Dein Problem:
Code:
            int d = 5;
            int intVal = Convert.ToInt32(Math.Round(d / 2.0));
Also einfach "2.0" statt "2" schreiben.

alzaimar 12. Dez 2009 13:20

Re: [.NET] Math.Round() macht mich verrückt
 
Was gefällt dir denn an diesem Code nicht?
Code:
int intVal = treeView.Height / 2;

Mithrandir 12. Dez 2009 13:23

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Matze
Code:
intVal = (int)(tView.Height/ 2)

Da merkt man das "C" in "C#". Ein Typecast rundet immer ab (oder, wenn man es wie Christian sagt, rundet gar nicht). Daher wäre dein Typcast auch möglich, wenn du denn das Ergebnis haben willst. Ansonsten ist es bei C (und offensichtlich auch bei C#) so, dass, sobald ein Operant ein Double-Wert ist, die Division mit Nachkommastellen von statten geht, ansonsten als Integer.

Daher wundert mich, dass, abhängig von der Deklaration von intVal, du das hier nicht nutzt:

Code:
intVal = tView.Height/ 2;
//Edit: Ach Mensch alzaimar, das war mein Part. :mrgreen:

Matze 12. Dez 2009 13:27

Re: [.NET] Math.Round() macht mich verrückt
 
Danke Christian, dann mache ich das so. :)

@Mark/Daniel: Ich habe immer ein ungutes Gefühl, wenn ich einem Integer einen Nicht-Integer zuweise, da damit irgendwas gemacht wird, was nicht auf den ersten Blick ersichtlich ist. Ich habe es gerne "typensicher", zumindest im Code. Ich mag zwar PHP mit seinen komplett fehlenden Typen, aber das ist eine andere Geschichte.
Wobei die Beschreibung von Convert.ToInt32() auch nicht einleuchtender ist.

Edit: Um nochmals auf die von mir angesprochene Problematik zurückzukommen:
Was ist der Sinn dahinter, dass Math.Round() bei fehlender Angabe der Nachkommastellen und somit einem Runden auf eine Ganzzahl einen Double zurück gibt? Das ist für mich völliger Blödsinn. :gruebel:

Christian S. 12. Dez 2009 13:32

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von alzaimar
Was gefällt dir denn an diesem Code nicht?
Code:
int intVal = treeView.Height / 2;

Das ist nicht äquivalent zum Runden, daher bin ich davon ausgegangen, dass Matze das nicht haben will.

Zitat:

Zitat von Matze
@Mark/Daniel: Ich habe immer ein ungutes Gefühl, wenn ich einem Integer einen Nicht-Integer zuweise

Bei alzaimars Code tust Du das nicht. Integer dividiert durch Integer ergibt in C# wieder einen Integer! Das Ergebnis ist halt nur nicht dasselbe bei beim Runden ;-)

Matze 12. Dez 2009 13:34

Re: [.NET] Math.Round() macht mich verrückt
 
Ich möchte damit nur eine Komponenten mittig positionieren. Also auf +/- einen Pixel kommt's mir da nicht an. Daher gingen beide Möglichkeiten.
Aber prinzipiell war es für mich mal interessant zu wissen, ob man das in C# bzw .NET sauber lösen kann. Meine Meinung ist: Jain mit Tendenz zu Nein. :stupid:

Christian S. 12. Dez 2009 13:43

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Matze
Aber prinzipiell war es für mich mal interessant zu wissen, ob man das in C# bzw .NET sauber lösen kann. Meine Meinung ist: Jain mit Tendenz zu Nein. :stupid:

Das kommt wohl ganz auf Deine eigene Defintion von sauber an. :wink:

Mithrandir 12. Dez 2009 13:58

Re: [.NET] Math.Round() macht mich verrückt
 
Ebens. Jeder C-ler würde in Tränen ausbrechen, würde man ihm erzählen, Typecasts seien schmutzig. :mrgreen:

sx2008 12. Dez 2009 14:08

Re: [.NET] Math.Round() macht mich verrückt
 
Schreib' Dir doch eine Klassenmethode oder Funktion namens RoundInt() die sämtliche Typecasts übernimmt.
Das hat zusätzlich den Vorteil, dass du Round() später durch etwas anderes ersetzen kannst.

Matze 12. Dez 2009 14:12

Re: [.NET] Math.Round() macht mich verrückt
 
Ja das geht natürlich. ICh wollte nur wissen, ob das mit Hausmitteln aus funktioniert. Dennoch danke für den Tipp.

Medium 12. Dez 2009 15:18

Re: [.NET] Math.Round() macht mich verrückt
 
Ich vermute mal, dass die Division durch eine Ganzzahl hier zusätzliche Verwirrung bringt. Ich mach's oft so:
Code:
someVal = (int)Math.Round(obj.IntProperty / 2.0);
das ".0" ist der wichtige Part hier, durch den die Division ein Double-Ergebnis liefert und damit eindeutig ist. Auch ginge es mit dem Suffix "f" hinter der 2, was dann in einem Single (float) resultieren würde.

Edit: Was man als Delphianer erstmal verinnerlichen muss ist, dass "/" bei Divisionen von zwei Ganzzahltypen dem "div" aus Delphi entspricht. Er wird aber zu einem Fließkomma-Operator, sobald eine solche beteiligt ist. Das Ergebnis des Operators entspricht dem genausten an der Division beteiligten Operanden, und nicht mehr.

alzaimar 12. Dez 2009 15:22

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Christian S.
Integer dividiert durch Integer ergibt in C# wieder einen Integer! Das Ergebnis ist halt nur nicht dasselbe wie beim Runden ;-)

Äh...nicht? :gruebel: Gib mal ein Beispiel.

Zitat:

Zitat von Matze
Ich möchte damit nur eine Komponenten mittig positionieren. Also auf +/- einen Pixel kommt's mir da nicht an.

Äh, na ja. halbe Pixel gibts nun mal nicht.

Zitat:

Zitat von Matze
...ob man das in C# bzw .NET sauber lösen kann. Meine Meinung ist: Jain mit Tendenz zu Nein. :stupid:

Das ist Gewohnheit. In Delphi würdest du das mit DIV lösen. C# ist da etwas transparenter.

Medium 12. Dez 2009 15:34

Re: [.NET] Math.Round() macht mich verrückt
 
Achso! Wenn du einfach nur das Verhalten von "div" willst, isses doch simpel:
Code:
someVal = obj.IntProperty / 2;
Da macht C# schon nur eine Integerdivision.

alzaimar 12. Dez 2009 15:40

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Matze
Um nochmals auf die von mir angesprochene Problematik zurückzukommen:
Was ist der Sinn dahinter, dass Math.Round() bei fehlender Angabe der Nachkommastellen und somit einem Runden auf eine Ganzzahl einen Double zurück gibt? Das ist für mich völliger Blödsinn. :gruebel:

Für mich wäre es Blödsinn, wenn eine Funktion mal double und mal int liefern würde.

Christian S. 12. Dez 2009 15:42

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von Christian S.
Integer dividiert durch Integer ergibt in C# wieder einen Integer! Das Ergebnis ist halt nur nicht dasselbe wie beim Runden ;-)

Äh...nicht? :gruebel: Gib mal ein Beispiel.

3/2 ergibt 1, während Math.Round(3/2.0) 2 ergibt.

Matze 12. Dez 2009 16:19

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von alzaimar
Für mich wäre es Blödsinn, wenn eine Funktion mal double und mal int liefern würde.

Da ist natürlich was dran. In Delphi nutze ich immer "System.Round", wenn ich auf ganze Zahlen runde und "Math.RoundTo" für das Runden auf Nachkommastellen. Daher ist mir das nie aufgefallen.

Btw: Auch seltsam, dass eine Runden-Funktion in "System" ist und eine in "Math". :mrgreen:

alzaimar 12. Dez 2009 17:30

Re: [.NET] Math.Round() macht mich verrückt
 
Zitat:

Zitat von Christian S.
3/2 ergibt 1, während Math.Round(3/2.0) 2 ergibt.

Ich werds nie lernen. :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz