![]() |
Nachkommastellen zählen
Hallo,
wie kann ich in C# die Nachkommastellen einer double-Zahl zählen? Für meine Zwecke reicht es auch erstmal zu ermitteln, ob die Zahl überhaupt welche hat, oder eine ganze Zahl ist. Mein Vater meinte, in Delphi macht man dies mit trunc oder so ähnlich. :? In C# hab ich aber bis jetzt nichts vergleichbares gefunden. :( Schonmal Danke im voraus JayK |
Re: Nachkommastellen zählen
Bei Double kannst du die Nachkommastellen durch die Fließkommaungenauigkeit schlecht zählen, da bräuchtest du Decimal (Festkommatyp).
Zitat:
Code:
public static bool IsInteger(double D)
{ const Double Epsilon = 1e-6d; return D - Math.Floor(D) < Epsilon; } |
Re: Nachkommastellen zählen
Zitat:
Zitat:
Wieso sollte man Ganzzahlen "nährungsweise" von anderen rationalen Zahlen unterscheiden? :stupid: |
Re: Nachkommastellen zählen
Zu dem Thema Ungenauigkeit von Fließkommazahlen:
![]() ![]() Zitat:
![]() ![]() Zitat:
Code:
double Value = 0.0d;
for (int i = 1; i <= 100; i++) Value += 0.01d; Console.WriteLine(Math.Floor(Value) == Value); Konsolenausgabe false Fließkommazahlen kannst du einfach nicht direkt vergleichen, da es eben z.B. 1 == 1.00000001 oder 1 == 0.999999 heißt. Hier nochmal mein Code, etwas ausführlicher:
Code:
Das ist dir hoffentlich klar :zwinker: .
public static bool IsInteger(double D)
{
Code:
Das ist die größte Abweichung, die D von seinem Ganzzahlwert haben darf, dieser Wert wird in der Mathematik mit "Epsilon" bezeichnet ("Sei Epsilon größer Null...").
const Double Epsilon = 1e-6d;
Code:
Hier gleich eine Verbesserung, hab gestern nur an 1.000001 gedacht :stupid: .
return Math.Abs(D - Math.Round(D)) < Epsilon;
Das gerundete D wird von D abgezogen, im oberen Beispiel wäre das dann -0.0000001 bzw. 0.0000001. Der Betrag dieser Subtraktion muss nun kleiner als Epsilon sein, damit wir ihn als "ziemlich Ganzzahl" durchlassen. |
Re: Nachkommastellen zählen
Okay, hoffe ich habs einigermaßen verstanden :?
Danke für die Erläuterung ;-) Und der Vollständigkeit halber zuliebe: Wie siehts bei decimal Zahlen aus mit der Nachkommastellenzählung? |
Re: Nachkommastellen zählen
Zitat:
Typen mit Nachkommaanteil (Beispiele): Single, Double, Extended, ... Ohne Nachkommaanteil (Beispiele): Integer, Word, Byte, Int64, ... Für alle der oberen Gattung gilt die bereits angesprochene Unmöglichkeit (bzw. nicht in jedem Fall gegebene Möglichkeit) die Nachkommastellen zu zählen, und für alle unteren gilt: Länge des Nachkommaanteils = 0 (per Definition schon ;)) Die einzige Chance die du hättest wäre ein ![]() Gruss, Fabian \\Edit: Und wenn man nun ganz pingelig ist, könnte man behaupten dass eine jede existierende Zahl unendlich viele Nachkommastellen hat. Nur ist in einigen Fällen der größte Teil davon 0 :mrgreen: |
Re: Nachkommastellen zählen
Zitat:
Zur Zählung der Nachkommastellen wäre es wahrscheinlich am besten, mit "unsafe code"die Variable in Mantisse und Exponent zu zerlegen, das Ergebnis müsste dann "Anzahl von Nicht-Null-Stellen der Mantisse von links - Exponent" oder so ähnlich sein. Allerdings gibt es nicht einmal in Hejlsbergs Buch eine genaue Beschreibung der decimal-Struktur. |
Re: Nachkommastellen zählen
Zitat:
Zitat:
Um also das Problem abschließend lösen zu können wäre eine Doku zum Aufbau von decimal nicht schlecht :) |
Re: Nachkommastellen zählen
Aufbau? Damit kann ich nicjh dienen :?
Ich hab aber rausgefunden: Decimal kann auch nur 28 Stellen (nicht Nachkommastellen) darstellen. Heißt aber trotzdem Festkommatyp :? Weiß aber immer noch nich, wie ich die Nachkomastellen von Decimal zählen kann... :-( Und weil ich vergessen habe, eine Sprache für den Thread festzulegen, möchte ich gerne noch wissen, wie man das mit Extended unter Delphi macht :mrgreen: Die Funktion von Khabarakh hat ja ordentlich funktioniert, wie würde die in Delphi aussehen? :?
Delphi-Quellcode:
Bei dem d hapert's. Das e nimmt er sogar schon an. :) (Ob richtig oder falsch weiß ich nich)
const Double Epsilon = 1e-6d;
|
Re: Nachkommastellen zählen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Delphi-Quellcode:
Fäst hätte ich vergessen, dass ich vor einer Woche ein Programm zum Auseinandernehmen von Decimal geschrieben habe:
const Epsilon = 1E-6;
Code:
Für alle ohne Framework ein paar Ergebnisse:
public static unsafe byte[] GetBytes(void* p, uint Length)
{ byte[] Bytes = new byte[Length]; byte* bytep = (byte*) p; for (int i = 0; i < Length; i++) { Bytes[i] = *bytep; bytep++; } return Bytes; }
Code:
1 =
Byte 0: 00000000 0 Byte 1: 00000000 0 Byte 2: 00000000 0 Byte 3: 00000000 0 Byte 4: 00000000 0 Byte 5: 00000000 0 Byte 6: 00000000 0 Byte 7: 00000000 0 Byte 8: 10000000 1 Byte 9: 00000000 0 Byte 10: 00000000 0 Byte 11: 00000000 0 Byte 12: 00000000 0 Byte 13: 00000000 0 Byte 14: 00000000 0 Byte 15: 00000000 0
Code:
1,00 =
Byte 0: 00000000 0 Byte 1: 00000000 0 Byte 2: 01000000 2 Byte 3: 00000000 0 Byte 4: 00000000 0 Byte 5: 00000000 0 Byte 6: 00000000 0 Byte 7: 00000000 0 Byte 8: 00100110 100 Byte 9: 00000000 0 Byte 10: 00000000 0 Byte 11: 00000000 0 Byte 12: 00000000 0 Byte 13: 00000000 0 Byte 14: 00000000 0 Byte 15: 00000000 0
Code:
Sollte man die Bits noch umdrehen? So sollte es aber stimmen:
-1,000000000000000000000 =
Byte 0: 00000000 0 Byte 1: 00000000 0 Byte 2: 10101000 21 Byte 3: 00000001 128 Byte 4: 01101100 54 Byte 5: 00000000 0 Byte 6: 00000000 0 Byte 7: 00000000 0 Byte 8: 00000000 0 Byte 9: 00000000 0 Byte 10: 00000101 160 Byte 11: 01111011 222 Byte 12: 10100011 197 Byte 13: 10110101 173 Byte 14: 10010011 201 Byte 15: 10101100 53
Code:
Byte 0-1: Unbenutzt
Byte 2: Exponent in Byte, 0 <= e <= 28 Byte 3: Vorzeichen, 128 = Negativ Byte 4-7: 16 Bit Ganzzahl, 2. Teil der Mantisse Byte 8-15: 32 Bit Ganzzahl, 1. Teil der Mantisse |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz