Laden...

Double: Bits in der Mantisse ermitteln

Erstellt von Qohelet vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.558 Views
Q
Qohelet Themenstarter:in
2 Beiträge seit 2011
vor 12 Jahren
Double: Bits in der Mantisse ermitteln

Hallo!

Ich bin gerade, eine recht interessante Aufgabenstellung zu lösen und stehe etwas an:

Schreiben Sie eine C# Methode, die für den Datentyp double die maximale Anzahl der Bits in der Mantisse feststellt und zurückgibt.

So wirklich maskieren lässt sich ein double-Wert nicht und meine Idee, den Wert auf 1 zu setzen, um ihn dann mit 0 AND zu verknüpfen, um zu zählen, wie viele 0en zwischen den beiden 1ern stehen zu zählen ist inzwischen auch gescheitert... Weiß jemand, wie ich in C# die einzelnen Bits auch bei double vergleichen oder sogar durchgehen kann?

Oder steuere ich überhaupt auf eine falsche Lösung hin?
Danke!

C
2.121 Beiträge seit 2010
vor 12 Jahren

Spiel mit Pointern und schreib den double in ein byte[8] Array. Da kannst du dann anders drin suchen.
Ich find die Aufgabe ziemlich seltsam. Da gibts meines Wissens nur eine feste Anzahl an Bits, warum dann eine maximale?

309 Beiträge seit 2008
vor 12 Jahren

Ich hätte die Aufgabe so gelöst:


static int GetBitCountInDoubleMantissa()
{
    return 52;
}

😉

Die Anzahl der Bits in der Mantisse bei double ist immer 52.

Also macht die Aufgabe IMHO keinen Sinn. Oder sind nur die belegten Bits gemeint, also Anzahl der Bits die die Mantisse tatsächlich genutzt werden?

Du kannst ja mal hier rein schielen: Looking inside a double

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}

C
2.121 Beiträge seit 2010
vor 12 Jahren

Ich nehm an man soll da irgendwas rechnen und daran dann die Anzahl rausfinden.
Vielleicht immer eine Stelle dazu rechnen, bis sich die Zahl nicht mehr ändert weil die Stellen ausgehen.
Klingt schwer nach Übungsaufgabe.

Q
Qohelet Themenstarter:in
2 Beiträge seit 2011
vor 12 Jahren

@chilic:
Genau das denke ich auch und mit einem Array wäre mir das ganze auch am liebsten, nur muss ich gestehen, dass ich nicht wirklich weiß, wie ich das umkonvertiere.

Mit dem Aufbau des Datentyps double hab ich mich natürlich beschäftigt, aber wie es Scavanger schreibt bin ich nicht wirklich glücklich, da ich ja nicht ausgeben soll, was ich nachschlagen kann, sondern ausrechnen, was anscheinend errechenbar ist.

In meiner Ausbildung hab ich zum Thema bitweise Operatoren und Strukturen nur die Grundlagen gelernt, allerdings nie effektiv damit gearbeitet, weswegen mich die Frage jetzt doch etwas fasziniert.

@Scavanger:
Interessant, auch wenn es mir nur bedingt hilft, da auch hier die Bitanzahlen als gegeben angenommen wurden...

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Qohelet,

eine Idee, den Wert auf 1 zu setzen, um ihn dann mit 0 AND zu verknüpfen, um zu zählen, wie viele 0en zwischen den beiden 1ern stehen zu zählen

mir ist weder klar, welche beiden Einsen du meinst, noch wie man durch Verknüpfen mit AND 0 etwas zählen kann.

nur muss ich gestehen, dass ich nicht wirklich weiß, wie ich das umkonvertiere.

Dann hast du dir den verlinkten Artikel nicht genau genug angeschaut. In dessen Code passiert ja genau das.

Wobei mir nicht klar ist, wie dir das helfen soll. Wenn du keine Annahmen über den Aufbau eines Doubles treffen darfst, weiß du ja gerade nicht, welche Bits was bedeuten.

Ich würde die Aufgabe anders verstehen. Dass du mit dem double ganz normal rechnen sollst und aus dem Auftreten von Abweichungen Schlüsse über die Genauigkeit ziehen sollst.

herbivore

S
401 Beiträge seit 2008
vor 12 Jahren

Mit dem Aufbau des Datentyps double hab ich mich natürlich beschäftigt, aber wie es Scavanger schreibt bin ich nicht wirklich glücklich, da ich ja nicht ausgeben soll, was ich nachschlagen kann, sondern ausrechnen, was anscheinend errechenbar ist.

Sicher ? 🤔

Wie sind den Fließkommazahlen nach IEEE 754 aufgebaut? Kleiner Tipp, bei der Mantisse wird eine Zahl immer "normiert". Die erste Zahl der Mantisse beginnt immer mit einer Eins. Somit muss die erste Zahl nicht gespeichert werden, da diese immer eine Eins ist.

Beispiel, Betrachtung des Betrags einer Zahl
Gegeben sei eine Zahl 001010100101110 Basis 2.
Die erste Eins wird verworfen 001010100101110. Somit muss nur 010100101110 gespeichert werden. Die rechte Seite wird noch mit weiteren 0 aufgefühlt.
Daher benutzt nach IEEE 754 jede Fließkommazahl alle zur verfügungstehende Bits + 1.
--> Double nach IEEE 754 benötigt 64bit im Speicher, besteht aber effektiv aus 66 bits.
Woher das zweite zusätzliche Bit kommt, überlasse ich dir. Das kann man auch nachlesen 😉

Gruß, Thomas

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Siassei,

Double nach IEEE 754 benötigt 64bit im Speicher, besteht aber effektiv aus 66 bits.

das kann ich so nicht stehen lassen.

Zwar ist es richtig, dass beim Speichern der (normierten) Mantisse in den 52 zur Verfügung stehenden Bits schlauerweise die erste Eins nicht mit gespeichert wird, wodurch am Ende der Mantisse eine Stelle mehr gespeichert werden kann und die Genauigkeit der Mantisse somit gegenüber dem naiven Ansatz steigt, aber der Informationsgehalt erhöht sich damit nicht auf 53 Bit. Wenn die erste Eins mitgespeichert werden würde, wäre der Informationsgehalt vielmehr nur 51 Bit, denn von dem ersten Bit würde dann ja nur einer von zwei Zuständen genutzt werden, eben die Eins. Durch das Weglassen der Eins werden nun die vollen 52 Bit genutzt, aber eben auch nicht mehr.

Das zweite zusätzliche Bit kommt deiner Meinung nach wohl daher, dass es beim Exponenten kein Vorzeichen-Bit gibt, sondern stattdessen mit einem Bias gearbeitet wird, um negative Exponenten darzustellen. Dadurch spart man aber nichts. Die Repräsentation ist anders, aber der Wertebereich des Exponenten wird dadurch nicht größer.

Für den Exponenten stehen 11 Bit zur Verfügung. Der Bias beträgt 1023. Damit wird der Wertebereich von -1022 bis 1023 abgedeckt, wobei zwei der möglichen 2^11 Zustände (00000000000 und 11111111111) Sonderbedeutungen haben. Wenn man die noch hinzunehmen würde, wäre der Wertebereich -1023 bis 1024.

Eine 10-Bit-Zahl mit einem zusätzlichen Bit als Vorzeichen hätte einen Wertebereich von -1023 bis 1023, wobei es zwei Repräsentationen für die 0 gäbe (+0 und -0). Eine 11-Bit-Zahl im Zweierkomplement (wie es auch von Int32 verwendet wird) hätte einen Wertebereich von -1024 bis 1023.

Die Wertebereiche sind also in alle drei Fällen (nahezu) gleich. Die kleinen Abweichungen könnte man durch Änderung des Bias um eins ausgleichen. Die Doppelrepräsentation der Null, würde auch nicht stören, da eh zwei der Zustände für Sonderbedeutungen abgezweigt werden müssen. Auf jeden Fall gibt es unabhängig von der Repräsentation immer die gleiche Menge an unterschiedlichen Exponenten, nämlich 2^11 = 2048. Hier spart man also definitiv nichts. Es kommt also auch kein Bit hinzu.

In 64 Bit kann man eben nicht mehr als 64 Bit speichern. Will sagen, mit 64 Bit kann man nur 2^64 verschiedene Zahlen repräsentieren. Mehr geht nicht. Weglassen kann man dabei nur Informationen, die den Informationsgehalt nicht ändert, wie in diesem Fall die stets konstante erste Eins der (normieren) Mantisse.

Über die Aussage, dass die Genauigkeit auf 65 Bit steigt, kann man sich als mindestens streiten. Ich sage, die Genauigkeit kann nicht auf über 64 Bit steigen. Da man beim Exponenten durch das Vermeiden eines expliziten Vorzeichen-Bits definitiv nichts spart, werden es aber auf keinen Fall 66 Bit.

herbivore

C
2.121 Beiträge seit 2010
vor 12 Jahren

Ich sage, die Genauigkeit kann nicht auf über 64 Bit steigen.

Kann sie ja auch wirklich nicht. Die Anzahl der darstellbaren Zahlen bleibt.
Man kann über die zusätzliche 1 praktisch Zahlen mit mehr Stellen in der Mantisse darstellen als tatsächlich Stellen verfügbar sind.
Die Genauigkeit der Zahlen ist dadurch besser. Aber dafür verschenkt man praktisch wieder kleinere Zahlen, denn das Verschieben der Bits in der Mantisse bis zur ersten 1 muss durch den Exponenten erfolgen. Hier geht der Vorteil dann wieder drauf.

U
1.688 Beiträge seit 2007
vor 12 Jahren

Hallo,

zum Konvertieren eines Double-Werts in ein Array nutzt man am einfachsten die BitConverter-Klasse.