AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Nachkommastellen zählen

Offene Frage von "JayK"
Ein Thema von JayK · begonnen am 31. Aug 2005 · letzter Beitrag vom 24. Sep 2005
Antwort Antwort
JayK

Registriert seit: 1. Mai 2005
49 Beiträge
 
#1

Nachkommastellen zählen

  Alt 31. Aug 2005, 18:53
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
nil
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#2

Re: Nachkommastellen zählen

  Alt 31. Aug 2005, 19:57
Bei Double kannst du die Nachkommastellen durch die Fließkommaungenauigkeit schlecht zählen, da bräuchtest du Decimal (Festkommatyp).
Zitat:
Für meine Zwecke reicht es auch erstmal zu ermitteln, ob die Zahl überhaupt welche hat, oder eine ganze Zahl ist.
Das bestimmst du am besten auch nur näherungsweise:
Code:
public static bool IsInteger(double D)
{
   const Double Epsilon = 1e-6d;
   return D - Math.Floor(D) < Epsilon;
}
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
JayK

Registriert seit: 1. Mai 2005
49 Beiträge
 
#3

Re: Nachkommastellen zählen

  Alt 1. Sep 2005, 16:55
Zitat von Khabarakh:
Bei Double kannst du die Nachkommastellen durch die Fließkommaungenauigkeit schlecht zählen, da bräuchtest du Decimal (Festkommatyp).
Ich muss aber double nehmen, weil ich die Zahlen u.a. mit Math.Sqrt() benutze. Und .net weigert sich decimal nach double (oder wars umgekehrt ) zu konvertieren.

Zitat von Khabarakh:
Zitat:
Für meine Zwecke reicht es auch erstmal zu ermitteln, ob die Zahl überhaupt welche hat, oder eine ganze Zahl ist.
Das bestimmst du am besten auch nur näherungsweise:
Code:
public static bool IsInteger(double D)
{
   const Double Epsilon = 1e-6d;
   return D - Math.Floor(D) < Epsilon;
}
Ich könnte das jetzt einfach Copy&Pasten, aber dann weiß ich überhaupt nicht, was in meinem Code vor sich geht
Wieso sollte man Ganzzahlen "nährungsweise" von anderen rationalen Zahlen unterscheiden?
nil
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#4

Re: Nachkommastellen zählen

  Alt 1. Sep 2005, 17:52
Zu dem Thema Ungenauigkeit von Fließkommazahlen: hier und hier

Zitat von JayK:
Und .net weigert sich decimal nach double (oder wars umgekehrt ) zu konvertieren.
Delphi-Referenz durchsuchenConvert.ToDouble bzw. Delphi-Referenz durchsuchenConvert.ToDecimal

Zitat:
Zitat von Khabarakh:
Zitat:
Für meine Zwecke reicht es auch erstmal zu ermitteln, ob die Zahl überhaupt welche hat, oder eine ganze Zahl ist.
Das bestimmst du am besten auch nur näherungsweise:
Code:
public static bool IsInteger(double D)
{
   const Double Epsilon = 1e-6d;
   return D - Math.Floor(D) < Epsilon;
}
Ich könnte das jetzt einfach Copy&Pasten, aber dann weiß ich überhaupt nicht, was in meinem Code vor sich geht
Wieso sollte man Ganzzahlen "nährungsweise" von anderen rationalen Zahlen unterscheiden?
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:
public static bool IsInteger(double D)
{
Das ist dir hoffentlich klar .
Code:
const Double Epsilon = 1e-6d;
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...").
Code:
return Math.Abs(D - Math.Round(D)) < Epsilon;
Hier gleich eine Verbesserung, hab gestern nur an 1.000001 gedacht .
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.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
JayK

Registriert seit: 1. Mai 2005
49 Beiträge
 
#5

Re: Nachkommastellen zählen

  Alt 1. Sep 2005, 19:13
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?
nil
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Nachkommastellen zählen

  Alt 1. Sep 2005, 21:39
Zitat von JayK:
Und der Vollständigkeit halber zuliebe: Wie siehts bei decimal Zahlen aus mit der Nachkommastellenzählung?
Was meinst du mit "dezimal"? Dezimal steht nur für Zahlen zur Basis 10, und sagt nichts darüber aus ob sie einen nachkommaanteil besitzen oder nicht.

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 Bei Google suchenFestkommatyp. Diese sind jedoch nicht generisch, und du müsstest sie komplett selbst implementieren oder auf evtl. vorhandere Lösungen zurückgreifen. Diese haben nur das Problem, dass sie meist nur begrenzt genau sind, oder aber einen kleinen Wertebereich besitzen da sie sich intern auf die Typen ohne Nachkommaanteil stützen in der Regel).

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
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: Nachkommastellen zählen

  Alt 2. Sep 2005, 08:27
Zitat von dizzy:
Zitat von JayK:
Und der Vollständigkeit halber zuliebe: Wie siehts bei decimal Zahlen aus mit der Nachkommastellenzählung?
Was meinst du mit "dezimal"? Dezimal steht nur für Zahlen zur Basis 10, und sagt nichts darüber aus ob sie einen nachkommaanteil besitzen oder nicht.
In C# ist schon ein Typ implementiert, mit dem sich Dezimalzahlen exakt darstellen lassen. Sein Name: decimal .
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.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Nachkommastellen zählen

  Alt 2. Sep 2005, 09:52
Zitat von Khabarakh:
In C# ist schon ein Typ implementiert, mit dem sich Dezimalzahlen exakt darstellen lassen. Sein Name: decimal .


Zitat von Khabarakh:
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.
Ich glaube auch nicht, dass decimal in einem Float-Format mit Mantisse und Exponent hinterlegt ist, weil dann wäre die Darstellung eben nicht mehr "exakt" möglich . Ich nehme daher an, dass es sich um eine fertige Implementierung eines Festkommatyps handelt, oder einen Float der in seinem Wertebereich zugunsten der Genauigkeit beschnitten ist, und eine max. Nachkommastellenanzahl kleiner der möglichen Genauigkeit definiert. Wobei ich bei letzterem auch bezweifle dass die Darstellung damit immer "exakt" möglich ist.

Um also das Problem abschließend lösen zu können wäre eine Doku zum Aufbau von decimal nicht schlecht
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
JayK

Registriert seit: 1. Mai 2005
49 Beiträge
 
#9

Re: Nachkommastellen zählen

  Alt 24. Sep 2005, 20:32
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
Die Funktion von Khabarakh hat ja ordentlich funktioniert, wie würde die in Delphi aussehen?
const Double Epsilon = 1e-6d; Bei dem d hapert's. Das e nimmt er sogar schon an. (Ob richtig oder falsch weiß ich nich)
nil
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#10

Re: Nachkommastellen zählen

  Alt 24. Sep 2005, 21:30
Zitat von JayK:
Ich hab aber rausgefunden: Decimal kann auch nur 28 Stellen (nicht Nachkommastellen) darstellen. Heißt aber trotzdem Festkommatyp
? Irgendwo muss schon eine Grenze sein (oder programmiert Hagen schon unter .NET ?) .

Zitat:
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
Die Funktion von Khabarakh hat ja ordentlich funktioniert, wie würde die in Delphi aussehen?
const Double Epsilon = 1e-6d; Bei dem d hapert's. Das e nimmt er sogar schon an. (Ob richtig oder falsch weiß ich nich)
Literale in Delphi haben keine "Kennung":
const Epsilon = 1E-6; Fäst hätte ich vergessen, dass ich vor einer Woche ein Programm zum Auseinandernehmen von Decimal geschrieben habe:
Code:
                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;
      }
Für alle ohne Framework ein paar Ergebnisse:
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:
-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
Sollte man die Bits noch umdrehen? So sollte es aber stimmen:
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
Angehängte Dateien
Dateityp: zip decimal_501.zip (8,4 KB, 4x aufgerufen)
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:21 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