Autor |
Beitrag |
C#
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Mo 28.05.12 20:57
Hey @ll,
ich habe mich gerade gefragt wie im System die Zahlen gerundet werden. Das Ergebnis findet ihr im Anhang als Bild, der Code dazu:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.Title = "Rundungstest"; Console.ForegroundColor = ConsoleColor.White;
ulong x = 9999999999999999999, y = 5000000000000000000; Console.WriteLine("{0} / {1} = {2}\tMit ulong / ulong", x, y, x / y); Console.WriteLine("{0} / {1} = {2}\tMit Math.Round(ulong, double)", x, y, Math.Round(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Floor(ulong, double)", x, y, Math.Floor(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Truncate(ulong, doub)", x, y, Math.Truncate(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit ulong / double\n\n", x, y, (x / (double)y));
x = 999999999999999; y = 500000000000000; Console.WriteLine("{0} / {1} = {2}\tMit ulong / ulong", x, y, x / y); Console.WriteLine("{0} / {1} = {2}\tMit Math.Round(ulong, double)", x, y, Math.Round(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Floor(ulong, double)", x, y, Math.Floor(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Truncate(ulong, double)", x, y, Math.Truncate(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit ulong / double\n\n", x, y, (x / (double)y));
x = 99999999999999; y = 50000000000000; Console.WriteLine("{0} / {1} = {2}\tMit ulong / ulong", x, y, x / y); Console.WriteLine("{0} / {1} = {2}\tMit Math.Round(ulong, double)", x, y, Math.Round(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Floor(ulong, double)", x, y, Math.Floor(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit Math.Truncate(ulong, double)", x, y, Math.Truncate(x / (double)y)); Console.WriteLine("{0} / {1} = {2}\tMit ulong / double", x, y, (x / (double)y)); Console.Read(); } } } |
Kann mir das jemand erklären?
Einloggen, um Attachments anzusehen!
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 28.05.12 21:42
Wenn du nicht explizit rundest, wird offensichtlich der ganzzahlige Anteil als Ergebnis benutzt. Also das gleiche wie Truncate. Sprich die Nachkommastellen werden ignoriert.
|
|
interessierter
      
Beiträge: 75
|
Verfasst: Mo 28.05.12 21:42
Hallo
Bin zwar Anfänger, aber vielleicht kann ich dir hier weiterhelfen
Dazu brauchst du Math.Round
Ich habe hier ein kleines Beispiel:
C#-Quelltext 1: 2: 3:
| double x = 2.34567; x = Math.Round(x, 2); Console.WriteLine(x); |
Hoffe es ist das was du suschst. Sonst gibts hier sicher jemand der dir weiterhelfen kann.
Grüsse
interessierter
Moderiert von Th69: C#-Tags hinzugefügt
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 28.05.12 22:25
Zitat: | Kann mir das jemand erklären? |
Du kannst es einfach nachlesen. An jeder Stelle der Math Klasse deren Methode du ja schon benutzt steht es dran. Für Gleitkommatypen wird 'IEEE 754' benutzt.
Wenn dir ein bestimmtes Ergebnis deines Tests spanisch vorkommt solltest du gezielt nach diesem fragen. Ich und bestimmt sonst auch keiner hat Lust jeden Einzeltest durchzukauen.
|
|
C# 
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Fr 01.06.12 13:11
Ok Sorry für die ungenaue Beschreibung und Danke für die Antworten.
Worauf ich hinaus möchte ist dass Math.Floor(double) - welches ja die nächst kleinere Ganzzahl ausgibt - und Math.Truncate(double) anscheinend nicht so genau arbeitet wie die normale Division von ulong / double. Wenn ich diese 2 Typen fülle, bis die fast Höchstmögliche Ziffernzahl erreicht ist (siehe 1. Post Code-Zeile 15), erreiche ich bei ulong / ulong immer noch korrekter weise 1. Bei Truncate und bei Floor erhalte ich jetzt jedoch 2.
C#-Quelltext 1: 2: 3: 4:
| ulong x = 9999999999999999999, y = 5000000000000000000; Math.Floor(x / (double)y) = 2 Math.Truncate(x / (double)y) = 2 x / y = 1 |
Wieso?
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 01.06.12 13:41
Für Floor und Truncate nimmst du vorher ein Division mit doubles vor. Bei der anderen Division eine mit ulongs. x hat aber mehr signifikante Stellen als man in einem double darstellen kann und verliert deshalb bei dem cast an Genauigkeit (Faustwert ist das double ungefähr 15 signifikante Stellen hat). Caste mal x direkt nach double und sieh dir den Wert an bzw. lass Truncate und Floor weg und betrachte nur die reine Division mit doubles. Da wird ebenfalls 2 rauskommen.
C#-Quelltext
|
|
C# 
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Fr 01.06.12 14:11
Achso Danke. Verliert double nur wegen der mögichen größe der Kommastellen seine Genauigkeit? ulong hat keine Kommastellen und ist deshalb exakt?
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 01.06.12 14:20
Zitat: | Achso Danke. Verliert double nur wegen der mögichen größe der Kommastellen seine Genauigkeit? |
Nein. Es geht um signifikante Stellen wo das Komma steht ist egal. 0,0 ..... hundert 0en ... 01 ist darstellbar genauso wie 1 ... hundert nullen ... 0,0 . Würden da jetzt aber nicht eine 1 stehen sondern eine Zahlenfolge unterscheidbar von 0 länger als 15 Ziffern wirst du, Prinzip bedingt, ungenau. Wenn du höhere Genauigkeit willst bei kleinerem Zahlenraum kannst du auf decimal anstatt double ausweichen.
Ansonsten am besten noch mal das Thema Gleitkommazahl zum Beispiel in Wikipedia nachlesen wo die prinzipiellen Problem liegen.
|
|
|