double - Datentyp

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.

double - Datentyp

Beitragvon RedGuy » 19.07.2016, 15:24

Hi zusammen !!!

Bei meinem aktuellen Projekt reize ich die Größen von Datentypen 1:1 aus. Das Ganze in C# .NET 2.0 .

Jetzt meine Frage: wie viele bits (also binär gesehen) sieht ein double - Typ für den ganzzahligen Bereich vor ?
Also was für eine Zweierpotenz steckt in einem double ?


Ich könnte das zwar ausrechnen. Vielleicht weiß es einer ja gerade auswendig oder hat ein paar Daten parat ;) .


Ergänzung: Ich suche also, denke ich, den Zweierlogarithmus von 4,94065645841246544E-324 . Ich finde allerdings keinen (Taschen-)rechner dafür :( ...


Gruss
RedGuy
RedGuy
Manuel Hofmann
Establishment
 
Beiträge: 111
Registriert: 17.09.2002, 17:27
Wohnort: Rottweil

Re: double - Datentyp

Beitragvon EyDu » 19.07.2016, 15:56

Hallo.

Am besten liest du dir dazu den entsprechenden Wikipedia-Eintrag durch:

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Da ist alles besser erläutert, als man hier eben mal schreiben könnte. Und wenn du schon dabei bist, mache gleich mit

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

weiter. Damit solltest du dann gerüstet sein ;-)
EyDu
 
Beiträge: 80
Registriert: 24.08.2002, 18:52
Wohnort: Berlin

Re: double - Datentyp

Beitragvon DerAlbi » 19.07.2016, 15:59

Du brauchst keinen Taschenrechner, wenn man etwas rechnen muss.
Den 2er-Logarithmus kann man sich z.B. von google ausrechnen lassen...
Google einfach mal nach "log(4,94065645841246544E-324)/log(2)" und du hast deine Antwort.

Ich finde das Ergebnis (-1074) aber angesichts des 11Bit-Exponenten aber etwas komnisch ^_^ vielleicht kann das jemand aufklären..
DerAlbi
Establishment
 
Beiträge: 206
Registriert: 20.05.2011, 05:37

Re: double - Datentyp

Beitragvon Krishty » 19.07.2016, 16:04

Ich verstehe die Frage so, dass er wissen möchte, wie viele fortlaufende ganzzahlige Werte er verlustfrei in einem double speichern kann. Das wäre zweimal die Kapazität der Mantisse (einmal positiv, einmal negativ) minus eins (weil die Null positiv und negativ vorkommt) …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
 
Beiträge: 6346
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy

Re: double - Datentyp

Beitragvon dot » 19.07.2016, 16:29

C# double folgt dem IEEE-754 binary64 Standard und hat daher eine 52-Bit Mantisse. Die Frage ist aber weiterhin: Wieso ist dir das wichtig?
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1629
Registriert: 06.03.2004, 19:10

Re: double - Datentyp

Beitragvon DerAlbi » 19.07.2016, 16:36

Njaaahh aber_fortlaufende_ Ganzzahlen kann man eigentlich double nicht speichern... man denke einfach nur mal an z.B: die "3". Dafür hat double, wie für so viele andere Zahlen, keine exakte Darstellung.
Deswegen wäre die Antwort vielleicht: es gibt keinen "ganzzahligen Bereich" im Datenraum des doubles oder irgendeines Floatingpoint-Formats. Es sind nunmal Gleitkommazahlen... die man ggf. durch eine verlustbehaftete Konvertierung auf Integers mappen kann...
DerAlbi
Establishment
 
Beiträge: 206
Registriert: 20.05.2011, 05:37

Re: double - Datentyp

Beitragvon Krishty » 19.07.2016, 16:50

DerAlbi hat geschrieben:man denke einfach nur mal an z.B: die "3". Dafür hat double, wie für so viele andere Zahlen, keine exakte Darstellung.
Doch: 1,5 * 2^1 ;) Guck hier: http://babbage.cs.qc.cuny.edu/IEEE-754/

Bis die Mantisse voll ist, lässt sich jedes int exakt darstellen. Sonst könnte ja z.B. JavaScript keine Schleifenzähler realisieren ;)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
 
Beiträge: 6346
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy

Re: double - Datentyp

Beitragvon RedGuy » 20.07.2016, 07:39

Hi !

@DerAlbi: Ups, ich hab die falche Zehnerpotenz gepostet. Die Zahl soll 1,79769313486231570E+308 lauten... Dann kommt man nämlich auf 1024.

@EyDu: Danke für die super Quelle(n) !!

Allerdings steht nirgendswo explizit die Zweierpotenz an sich.
Aus dem IEEE 754 double-precision binary floating-point format könnte ich nur wieder die 1,79769313486231570E+308 berechnen. Darüberhinaus komme ich nicht weit (bezüglich der Zweierpotenz).

@krishty:
Damit komme ich irgendwie nicht zurecht. Ist die Mantisse nicht einfach die 1,79769313486231570 ??

---

Also das Resultat wäre also: in einem double steckt als höchste Zweierpotenz die 2^1024,
da log2(1,79769313486231570E+308) = 1024.

Aber das kann nicht stimmen, denn selbst bei 2^63 ist wird double schon wieder negativ (fängt von vorne an) - das habe ich ausprobiert.
RedGuy
Manuel Hofmann
Establishment
 
Beiträge: 111
Registriert: 17.09.2002, 17:27
Wohnort: Rottweil

Re: double - Datentyp

Beitragvon RedGuy » 20.07.2016, 08:16

Hi !!!

Also habe nun das entgültige Resultat:

die höchste Zweierpotenz in einem double ist 2^63 = 9,22337203685478E+18

die höchste Zweierpotenz nach einem type cast von double nach long, welche eine nicht negative Zahl ergibt
ist allerdings seltsamerweiße 2^62 = 4611686018427387904 . Da geht wohl bei der Konvertierung was verloren, denn
ein long müsste ja normalerweiße 2^63 (+1bit Vorzeichen) aufweisen.



Um das herauszufinden habe ich folgende Programme geschrieben:

Code: Ansicht erweitern :: Alles auswählen
static void Main(string[] args)
{
for ( byte pos = 63 ; pos >= 0 ; pos-- )
{
double currentNumber = Math.Pow(2.0d, (double)pos);

if ( currentNumber > 0.0d )
{
Console.WriteLine(pos + ", " + currentNumber);
break;
}
}

Console.ReadLine();
}



bzw.

Code: Ansicht erweitern :: Alles auswählen
static void Main(string[] args)
{
for ( byte pos = 63 ; pos >= 0 ; pos-- )
{
long currentNumber = (long)(Math.Pow(2.0d, (double)pos));

if ( currentNumber > 0 )
{
Console.WriteLine(pos + ", " + currentNumber);
break;
}
}

Console.ReadLine();
}



Es gibt mir einfach die erste höchste Zweierpotenz heraus,
bei der ein double (bzw. ein long) nicht wieder bei negativ beginnt.


@dot: Ich hab also anstatt 62bits, 63bits heraus. Beim Long komme ich auch auf 62bits.
Ich will das wissen, da ich explizit die Datengröße ausreizen muss. Also z.B. binär die 62bits...

Gruss
RedGuy
Manuel Hofmann
Establishment
 
Beiträge: 111
Registriert: 17.09.2002, 17:27
Wohnort: Rottweil

Re: double - Datentyp

Beitragvon Schrompf » 20.07.2016, 08:46

Du bist wirklich wirklich wirklich auf dem falschen Dampfer. Dein Testprogramm berechnet, wie groß ein long ist. Aber nicht, bis zu welcher Zahl ein double eine Ganzzahl verlustfrei darstellen kann. Die Zweierpotenzen sind im Double bis 2^(2^(ExponentBits-1)) exakt darstellbar. Ein double hat 11 Bits Exponent als Zweierkomplement (glaube ich jedenfalls), also ist 2^(2^10) das Maximum, was Du insgesamt darstellen kannst. Das sind die vorhin genannten 1,8e+308. Was Du eigentlich nachprüfen müsstest, wäre die größte Zweierpotenz, bis zu der 2^x -1 noch exakt darstellbar wäre. Und das ist wie schon genannt 2^52.

Erklärung: Stell Dir eine Fließkommazahl so vor, wie als hättest Du eine Reihe Ziffern, und Du kannst Dir aussuchen, wo in der Ziffernfolge das Komma stehen soll. So in etwa:

123456789098765,0

oder

123456789,098765

oder

12345,6789098765

oder halt

0,123456789098765

Da hört es aber nicht auf. Fließkommazahlen können das Komma noch viel weiter raus setzen. Stell Dir also einfach Nullen vor, bis das Komma kommt. Also etwa so:

0,00000000123456789098765

oder in die Gegenrichtung:

1234567890987650000000000000,0

Der Exponent der Fließkommazahl bestimmt, wie weit raus Du das Komma schieben kannst. Aber Du willst wissen, wieviele Ganzzahlen Du verlustfrei darstellen kannst. Und das leitet sich nur aus der Anzahl Ziffern ab, also der Mantisse, weil Du für diesen Fall die Position des Kommas auf die Einerstelle festlegst.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
Schrompf
Thomas Ziegenhagen
Moderator
 
Beiträge: 3684
Registriert: 26.02.2009, 00:44
Wohnort: Dresden
Benutzertext: Lernt nur selten dazu

Re: double - Datentyp

Beitragvon RedGuy » 20.07.2016, 09:19

Hi !

@Schrompf:
Also zunächst einmal Danke für deine Antwort.
Diese müsste ich allerdings ersteinmal studieren, da ich diese auf Anhieb nicht kapiere.


Aber grundsätzlich: Was ist falsch an meinem Testprogramm, die "Größe" (Zweierpotenz) vom double - Typ zu Fuß herauszufinden ?!?!
Das müsste doch eigentlich funktionieren ;) .

Gruss
RedGuy
Manuel Hofmann
Establishment
 
Beiträge: 111
Registriert: 17.09.2002, 17:27
Wohnort: Rottweil

Re: double - Datentyp

Beitragvon Matthias Gubisch » 20.07.2016, 10:25

Vielleicht so:

es gibt bei Flieskommazahlen einen Unterscheid zwischen der absolut maximal darstellbaren Zahl und der maximal "verlustfrei" darstellbaren Zahl.

Dein Testprogramm berechnet die absolut maximal darstellbare Zahl eines double wenn ich das richtig sehe.
Die ist im Endeffekt: MAX(Mantisse) * 2^Exponent

Die höchste Verlustfrei darstellbare Zahl sollte auf den ersten Blick MAX(Mantisse) sein.
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Matthias Gubisch
Establishment
 
Beiträge: 260
Registriert: 01.03.2009, 20:09

Re: double - Datentyp

Beitragvon joggel » 20.07.2016, 11:29

Mal ne Frage von mir zwischendurch:
Ist es denn immer garantiert, das bei einem double-typ *ausschließlich* und *nur* die Mantisse zur darstellung verwendet wird, wenn die darzustellende Zahl kleiner als 2^52 ist?
bald mit neuem Avatar
Benutzeravatar
joggel
Establishment
 
Beiträge: 1295
Registriert: 06.11.2007, 19:06
Wohnort: Dresden

Re: double - Datentyp

Beitragvon Matthias Gubisch » 20.07.2016, 11:42

@RedGuy
hier: https://en.wikipedia.org/wiki/Double-pr ... int_format
und hier: https://docs.oracle.com/cd/E19957-01/80 ... dberg.html

ist die ganze Sache mit Floating Point und was ist warum darstellbar ganz gut erklärt.

@joggel:
Achtung Vermutung: Das hängt stark vond einer Zahl ab. Wenn du garantieren kannst dass die darzustellende Zahl eine Ganzzahl ist...., sobald Nachkommastellen ins Spiel kommen reicht die Mantisse ja nicht mehr aus.
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Matthias Gubisch
Establishment
 
Beiträge: 260
Registriert: 01.03.2009, 20:09

Re: double - Datentyp

Beitragvon joggel » 20.07.2016, 12:01

Ja, ich meinte halt auch nur ganzzahlige Werte.
Was mich nur verwundert hat:
Krishty hat geschrieben:
DerAlbi hat geschrieben:man denke einfach nur mal an z.B: die "3". Dafür hat double, wie für so viele andere Zahlen, keine exakte Darstellung.
Doch: 1,5 * 2^1 ;) Guck hier: http://babbage.cs.qc.cuny.edu/IEEE-754/
[...]

Wenn für die "3" dazu die Mantisse doch aber ausreicht, wieso diese Zahl dann in eine "echte" Fließkommazahl umwandeln?

p.s.:
Passend zu dem Thema gerade gefunden^^
http://www.h-schmidt.net/FloatConverter/IEEE754de.html

Dank diesem IEEE 754-Umrechner verstehe ich das jetzt wie das mit den Fließkommazahlen läuft! :)
@RedGuy
Schaue dir diesen Umrechner mal an ;)
bald mit neuem Avatar
Benutzeravatar
joggel
Establishment
 
Beiträge: 1295
Registriert: 06.11.2007, 19:06
Wohnort: Dresden

Re: double - Datentyp

Beitragvon Schrompf » 20.07.2016, 13:53

Schöner Fund, der ist wirklich gut!
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
Schrompf
Thomas Ziegenhagen
Moderator
 
Beiträge: 3684
Registriert: 26.02.2009, 00:44
Wohnort: Dresden
Benutzertext: Lernt nur selten dazu

Re: double - Datentyp

Beitragvon Spiele Programmierer » 20.07.2016, 13:54

Hier scheint es ja erstaunlich viel gefährliches Halbwissen zu Gleitkommazahlen zu geben.
Alle Ganzzahlen von inklusive -2^53 bis 2^53 sind mit double exakt darstellbar. Ja - es ist mehr als ±2^52...

Jede Gleitkommazahl stellt eine Zahl wie folgt dar:
Vorzeichen * Mantisse * 2^Exponent
  • Das Vorzeichen verwendet immer ein Bit und entweder +1 oder -1. (Sollte klar sein)
  • Die zur Mantisse verwendeten Bits stellen eine Zahl zwischen 1 und 2 dar. (!)
  • Die Mantissenwerte sind linear verteilt. Wäre die Mantisse 3 Bits groß, könnte die Mantisse folgende 8 Werte annehmen:
    1, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875
    Die Zahlen ergeben sich so:
    1, 1 + 2^-3, 1 + 2*2^-3, 1 + 3*2^-3, 1 + 4*2^-3, 1 + 5*2^-3, 1 + 6 * 2^-3, 1 + 7 * 2^-3 (= 2 - 2^-3)
  • Die verbleibenden Bits fallen an den Exponenten. (Der Exponent kann negativ sein - für Zahlen kleiner 1)

Für die Zahl 3 ist ist das Vorzeichen positiv, die Mantisse 1.5 und der Exponent 1:
+1 * 1.5 * 2^1 = 1.5 * 2 = 3
Bei double Zahlen ist für 2^53 - 1 ist die Mantisse 2 - 2^-52 (≈ 1.99999...). Und der Exponent 2^52:
+1 * (2-2^-52) * 2^1 = +1 * 1.999999... * 2^52 = 9007199254740991
2^53 geht auch noch - die Mantisse 1 ist exakt darstellbar:
+1 * 1 * 2^53 = 9007199254740992

Obwohl die Mantisse nur 52 Bits hat, sind die Zahlen bis 2^53 exakt darstellbar. Das liegt daran, dass die Mantissenwerte eben zwischen 1 und 2 liegen. Der Exponent ist somit 1 kleiner als im ersten Moment vlt. anzunehmen. Das Konzept nennt sich auch "Hidden Bit". Wäre das nicht so, gäbe es auch mehrere Möglichkeiten, die selbe Zahl darzustellen. (Das wären dann verschwendete Darstellungsweisen für sinnvolle Informationen)

Erst ab 2^53+1 gibt es Probleme, weil die Mantissenwerte nur 2^-52 auseinander liegen, der Exponent jetzt aber inzwischen bei 2^53 angelangt ist. Die nächste double Gleitkommazahl größer als 2^53, hat eine Mantisse um 2^-52 größer. Das ist dann:
+1 * (1+2^-52) * 2^53 = +1 * 1.000000... * 2^53 = 9007199254740994
9007199254740993 ist damit die erste natürliche Zahl, die nicht als Gleitkommazahlen doppelter Genauigkeit darstellbar ist.

Es gibt zwei Ausnahmen zu dieser Regel, dass die Mantisse eine Zahl zwischen 1 und 2 beschreibt. Und das sind die beiden Extremen, nahe 0 und sehr große Zahlen. Die sogenannten denormalisierten Gleitkommazahlen und die Unendlichkeit.
  • Denormalisierte Gleitkommazahlen sind eine Ausnahme um die 0 darstellen zu können. (außerdem ein paar andere sehr kleine Zahlen)
    Wenn der Exponent den minimalen Wert annimmt (bei double -1023), beschreibt die Mantisse eine Zahl den Bereich 0 bis 2! Dadurch wird die Null speicherbar (als 1 * 0 * 2^-1023). Das ist der Grund, warum die kleinste positive double Zahl nicht +1 * 1^-1023 ≈ 1.11*10^-308 ist, sondern +1 * 2^-51 * 2^-1023 ≈ 4.94*10^-324. Je nach Bibliothek und Programmiersprache gibt es unterschiedliche Ansichten, was denn nun die kleinste positive Gleitkommazahl ist. DBL_MIN in C(++) ist z.B. ~2.22e–308, obwohl es durchaus kleinere positive Zahlen gibt.
  • Unendlichkeiten sind eine Ausnahme um den Überlauf zu kennzeichnen.
    Wenn der Exponent den maximalen Wert annimmt (bei double 1024), ist der Wert unendlich. Mit dem Vorzeichenbit gibt es auch noch negativ unendlich. Die Mantisse ist ungenutzt. Falls ein Bit in der Mantisse gesetzt ist, wird die Zahl als Not a Number (NaN) interpretiert.

Ist es denn immer garantiert, das bei einem double-typ *ausschließlich* und *nur* die Mantisse zur darstellung verwendet wird, wenn die darzustellende Zahl kleiner als 2^52 ist?

Was stellst du dir darunter vor, "nur die Mantisse" zu verwenden? Eine Gleitkommazahl hat immer die 3 Teile gleicher Größe.
Zuletzt geändert von Spiele Programmierer am 20.07.2016, 14:04, insgesamt 2-mal geändert.
Spiele Programmierer
Establishment
 
Beiträge: 341
Registriert: 23.01.2013, 16:55

Re: double - Datentyp

Beitragvon MasterQ32 » 20.07.2016, 13:59

Danke! Ich war zu faul, das jetzt so ausführlich zu schreiben und kürzer ist es irgendwie sinnlos :P
Duct tape is like the force. It has a light side, a dark side, and it holds the world together.
Benutzeravatar
MasterQ32
Felix Queißner
Establishment
 
Beiträge: 1108
Registriert: 07.10.2012, 14:56


Zurück zu Algorithmen und Datenstrukturen

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast