Stefan_j Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Hallo! Ich habe folgendes Problem: Ich kann zwar den Binärwert einer Dezimalzahl schön und richtig (durch Bitshifting) am Bildschirm ausgeben: int value = 103179880; int i = 0; int int_bit_size = 32; for(i = 0; i < int_bit_size; i++){ printf("%d", (value & 0x80000000) >> 31); value <<= 1; } aber wie kann ich diesen Binärwert in einer Variable speichern?? Lg Stefan Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Speichere sie doch in einem Byte bzw mehreren Bytes. Phil Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 hmm.. dazu müsste ich aber vorher wieder alle bits extra ausgeben.. und genau da liegt mein problem diese werte zu speichern! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Daten werden immer Binär gespeichert, alles andere ist nur Darstellungssache Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Daten werden immer Binär gespeichert, alles andere ist nur Darstellungssache Offensichtlich soll die Binärdarstellung gespeichert werden. Das einfachste wäre wohl, sprintf zu benutzen, und alle Einzelergebnisse zusammenzuhängen (strcat). Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Hmm, ich versteh das Problem nicht so recht. Du hast doch bereits 32 bits in einem signed int gespeichert? Meinst Du zum Zwischenspeichern einzelner Bits? Es gibt bool, aber auf einem 16bit System oder höher ist das ohnehin Verschwendung und nur der besseren Lesbarkeit her ok. In C++ gibt zum Beispiel auch bitset. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 Ich will eine Gleitkommazahl (Typ float) in einen ASCII String konvertieren! Dazu brauche ich den Wert der Mantisse (und der ist in Binärform)! Ich will das komplette Binärmuster speichern zB (10001101..) Problem: for(i = 0; i < int_bit_size; i++){ printf("%d", (value & 0x80000000) >> 31); value <<= 1; } Wenn ich anschließend value ausgeben will bleibt nur der wert des letzten bits erhalten (also 0 oder 1) brauche aber das ganze Bitmuster!!! printf("%d\n",value); --> = 0 oder 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 das heißt ich habe das Bitmuster am Bildschirm zwar ausgegeben, aber ich kann damit nicht weiter rechnen!! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Dazu brauche ich den Wert der Mantisse (und der ist in Binärform)!Alles, was im Computerspeicher liegt, ist in Binärform, weil der Computer nichts anderes beherrscht. Ich will das komplette Binärmuster speichern zB (10001101..)Ist dir klar, dass der Wert derselbe ist, egal welche Darstellung du benutzt? Wenn ich anschließend value ausgeben will bleibt nur der wert des letzten bits erhalten (also 0 oder 1) brauche aber das ganze Bitmuster!!!Das liegt daran, dass value während der Berechnung zerlegt wird. Das "Bitmuster" war vorher in value. Wenn du das später nochmal anzeigen musst, dann kopier den Wert doch einfach vorher in eine andere Variable. das heißt ich habe das Bitmuster am Bildschirm zwar ausgegeben, aber ich kann damit nicht weiter rechnen!!Die Binärdarstellung ist ein Text, mit dem kannst du sowieso nicht rechnen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Crash2001 Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Meine ich das nur, oder wird die Variable in der Schleife da jedesmal überschrieben? (ist schon eine ganze Weile her, dass ich das letzte mal was mit C zu tun hatte ) Dann könnte die am Ende ja nicht den kompletten Wert enthalten, sondern nur den Endwert nach Durchlaufen der Schleife. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 Naja die Aufgabenstellung ist auf jeden Fall folgende: Die Konvertierung einer Gleitkommazahl zu einem ASCII-String kann mit Hilfe des folgenden Algorithmus berechnet werden: 1. Berechne Mantisse und Exponent der Gleitkommazahl wie im vorherigen Beispiel beschrieben. --> Alles klar 2. Denormalisiere die Zahl, sodass der Exponent 0 ist. Dies erreicht man durch Shiften der Binärzahl. --> auch klar 3. Konvertiere die binäre Zahl vor dem Komma in die dezimale Darstellungsform. Dies kann man durch Addition aller Binärwerte, die mit ihrem Stellenwert 2i multipliziert werden, erreichen, wobei k das höchstwertige Bit (MSB) ist. Danach erhält man den entsprechenden ASCII-Wert durch die Addition mit dem ASCIIWert der Ziffer '0'. --> daher brauche ich die Binärwerte zum weiterrechnen! (jeweiliges Bit * 2 ^exponent) 4. Konvertiere nun auch die binäre Zahl nach dem Komma in die dezimale Darstellungsform. Diese Zahl kann wie folgt berechnet werden: wobei j das niederwertigste Bit (Least Signicant Bit - LSB) darstellt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Hier steht doch alles... :floet: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 Werd das mal ausprobieren! Jedenfalls Danke für die Hilfe! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Meine ich das nur, oder wird die Variable in der Schleife da jedesmal überschrieben? Nein, wird nicht direkt überschrieben, denn in: printf("%d", (value & 0x80000000) >> 31); ist der Bereich um value nur ein rvalue, also nix geschrieben und in: value <<= 1; // value = value << 1 bit shift links um 1 bit und rechts mit 0 auffüllen. das bedeutet, dass in jedem Schleifendurchlauf an der 32.Stelle (MSB) das printf() kommt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 das heißt im endeffekt ist nur mehr das MSB in der variable und alle anderen sind 0! gibt es eine Möglichkeit vor jedem bitshift zB mit strcat oder sprintf die bits in eine (andere) variable einzulesen?? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 gibt es eine Möglichkeit vor jedem bitshift zB mit strcat oder sprintf die bits in eine (andere) variable einzulesen?? Ja, indem du die Funktion einfach vor dem Shift aufrufst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Mal ganz davon abgesehen, kann ich immer noch nicht ganz das Problem mit dem Code inbezug auf die Aufgabenstellung begreifen. Du willst den Vorkommateil eines float, den Du bereits als int hast durch Summieren der bit-Wertigkeiten in Dezimaldarstellung haben und als zweiten Schritt durch Addieren des ASCII-Wertes der '0' als ASCII darstellen? int i, dezimal = 0, mask = 1; for ( i = 0; i < 32; ++i ) { dezimal += (value & mask) ? mask : 0; printf("%d & %x = %d => %d \n", value, mask, value&mask, dezimal); //debug mask <<= 1; } Damit summierst Du die binärwerte; Wieviele Stellen kann ein int als Text maximal haben? 10+1Vorzeichen also passt char[12] while ( dezimal ) { char c = '0' + dezimal % 10; // mit strcat in textpuffer schreiben dezimal /= 10; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 konkret ist die Aufgabenstellung so: Umwandlung einer 32Bit-Gleitkommazahl (also float) in einen String (ASCII-Zeichen). Es müssen mind. 4 Vorkomma- und 4 Nachkommastellen umgewandelt werden unter Verwendung simpler Bitoperationen wie shift, and, or, subtract. Die C-Version soll dann als Vorlage für denselben Vorgang in Assembler dienen.. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 falls das was hilft: So wäre die Lösung für einen Integer-Wert, ich suche die Lösung für einen float-Wert! void RNOInteger::toASCII_c(char str[]) { int int32=value; char c; int i = 0; do { str[i++]=int32 % 10 + '0'; int32 /= 10; } while (int32 > 0); str[i--] = '\0'; // reverse order for (int x = 0, y = i; x<y; x++, y--) { c = str[x]; str[x] = str[y]; str[y] = c; } } Das ist die header-Datei dazu: #ifndef RNOINTEGER_H_ #define RNOINTEGER_H_ #include <iostream> using std::ostream; typedef unsigned int UInt32; class RNOInteger { private: UInt32 value; public: RNOInteger(void); // default constructor RNOInteger(UInt32 val); // constructor to initialize instance with 32-bit integer ~RNOInteger(void); // destructor void toASCII_c(char str[]); // conversion into ASCII in C void toASCII_asm(char str[]); // conversion into ASCII in Assembler friend ostream& operator << (ostream&, const RNOInteger&); }; // Input- and output operators ostream& operator << (ostream& outstr, const RNOInteger& RNOInt); #endif /* RNOINTEGER_H_ */ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 hmm, die Lösung für den int schaut ziemlich so aus, wie mein Vorschlag, ich hab aber tatsächlich, das reverse vergessen. Fakt ist ein float (single nach IEEE 754, Link zu wiki wurde bereits hier gepostet) besteht aus 23 bit Mantisse vom LSB ab, dann 8 bit Exponent und 1 bit Vorzeichen (MSB). Jetzt musst du nur noch aus dem float zwei int's machen (ein Vorkomma-Int und ein Nachkomma-Int) und die umwandeln. In der Aufgabenstellung steht sogar schon was wegen denormalisieren, ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AndiE Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Hallo, das ist ein interessantes Thema. Mit float f=3.1415926f; kann ich eine Zahl abspeichern und mit adr=&f; die Adresse der Zahl abfragen. Aber wie bekomme ich daraus die vier Byte, in denen die Zahl dargestellt wird? Mit (char)*adr geht das nicht- Ergebnis=0. Ich glaube, mal gelesen zu haben, es ginge mit "bitfields". Aber ich weiß nicht mehr genau. Ich musste mal ein Programm schreiben, das aus einer Folge von 0 und 1 die dazugehörige Dizimalzahl berechnet. Aber wie bekomme ich eine float-Zahl dazu, mir ihre vier Byte zu übergeben? LG André Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 12. März 2009 Teilen Geschrieben 12. März 2009 Hallo, Aber wie bekomme ich eine float-Zahl dazu, mir ihre vier Byte zu übergeben? naja, float ist genauso groß wie ein int (auf 32 bit systemen). Deshalb kannst du einen erzwungenen typecast machen, direkt den speicher kopieren oder gleich mit nem union zugreifen. Aber aus den 4 bytes wird dann trotzdem nur über Bitpobelei irgendetwas anderes wie eine Dezimalzahl Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Stefan_j Geschrieben 12. März 2009 Autor Teilen Geschrieben 12. März 2009 Danke für die Hilfe! Bin jetzt schon gut im Rennen Was geht: Habe den float in 2 int's eingelesen (ganzzahl und rest) Vorzeichen berechnen Exponenten berechnen binäre (reduzierte & erweiterte) mantisse ausgeben normierte mantisse/denormalisierte mantisse in dezimal und binärwerten ausgeben Das einzige Problem noch: ich bekomm als ascii-code bei ganzzahl 2345 und bei rest 1 raus, das kann nicht ganz richtig sein?? void RNOFloat::toASCII_c(char str[]) { // add your c code of the algorithm here float RNOFloat = value; //Gleitkommazahl, die konvertiert werden soll unsigned int *ptr, bit, maske; int i, exp, vorzeichen; int ganzzahl = abs( static_cast<int>(RNOFloat) ); printf("\nGanzzahl: %d",ganzzahl); printf("\n"); int rest = abs ( static_cast<int>((RNOFloat - ganzzahl) * 100000)); printf("Rest: %d",rest); printf("\n\n"); ptr = (unsigned int*) &RNOFloat; bit = *ptr; maske = 1 << 31; // maske = (unsigned int) 1 << 31; printf("Vorzeichen: "); if (maske & bit){ //maske & bit filtert das Vorzeichen-Bit heraus; Bitweiser Vergleich; 0 positiv; 1 negativ printf("1"); vorzeichen = 1; } else { printf("0"); vorzeichen = 0; } printf("\nExponent: "); exp = 0; //Initialisierung for (i=0; i<8; i++){ //durchlaufe Schleife bis i=8 --> float: Exponent hat 8 Bits; maske >>= 1; exp <<= 1; if (maske & bit){ exp++; } } exp -= 127; //von exp wird der BIAS-Wert von 127 abgezogen printf("%d\n", exp); printf("erweiterte binäre Mantisse: 1."); //1 wird eingefügt, dahinter folgt die reduzierte Mantisse for (i=0; i<23; i++){ //23 Bits für Mantisse reserviert; IEEE754 maske >>= 1; if (maske & bit){ printf("1"); } else { printf("0"); } } //Schritt 1 erledigt: Berechnung Mantisse, Exponent und Vorzeichenbit //Schritt 2: denormalisieren der Mantisse, dies wird im Binärsystem durch shiften erreicht (dezimal: * 2^3) //m = x/2^exp float norm_mantisse = RNOFloat/pow(2.0,exp); printf("\n\nDezimaldarstellung:\nnormierte Mantisse: %f\n", norm_mantisse); //Norm. Mantisse = erw. Mantisse dez./2^23 // --> erw. Mantisse dez. = norm. Mantisse * 2^23 int erw_mantisse = norm_mantisse * pow(2.0,23.0); printf("Erweiterte Mantisse: %d", erw_mantisse); int den_mantisse = erw_mantisse * pow(2.0,3.0); printf("\nDenormalisierte Mantisse: %d\n", den_mantisse); printf("Binaerwert: "); //Berechnung binäre denorm. Mantisse: int int_bit_size = 0; int_bit_size = sizeof(int) * 8; for(i = 0; i < int_bit_size; i++){ printf("%d", (rest & 0x80000000) >> 31); rest <<= 1; } printf("\n"); char c; i = 0; do { str[i++]= ganzzahl % 10 + '0'; cout << str; ganzzahl /= 10; } while (ganzzahl > 0); str[i--] = '\0'; // reverse order for (int x = 0, y = i; x<y; x++, y--) { c = str[x]; str[x] = str[y]; str[y] = c; } //Rest printf("\n"); i=0; do { str[i++]= rest % 10 + '0'; cout << str; rest /= 10; } while (rest > 0); str[i--] = '\0'; // reverse order for (int x = 0, y = i; x<y; x++, y--) { c = str[x]; str[x] = str[y]; str[y] = c; } printf("\n"); } Ist das soweit richtig? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 13. März 2009 Teilen Geschrieben 13. März 2009 Neeeeein, sorry. Ich hab AndiE gemeint mit dem erzwungenen typecast. Das hilft Dir nicht. Tut mir wirklich leid, ich hätte das besser von Deinem Threadthema abgrenzen müssen. Du warst zu anfangs schon richtig. Du darfst das nicht einfach casten, denn das ist nur eine andere Darstellung der 4 bytes, die im Speicher stehen, aber darauf wird keine Mantisse/Exponent etc. Fakt ist Du musst - wie oben beschrieben - die Mantisse den exponenten und das Vorzeichen aus den 4 bytes des float rausholen. und zwar mit Bitpopelei. Aber bitte beachte dazu einfach die Dinge, die auf der wiki-Seite stehen. Ich wäre sogar so frech und würde einfach den float über die angesprochene Bitpobelei in einen Vorkomma- und Nachkomma-Int schreiben und dann mit der Funktion Int_toASCII umwandeln und zusammensetzen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AndiE Geschrieben 13. März 2009 Teilen Geschrieben 13. März 2009 Hallo, ich habe mal gerechnet: die Zahl 3,1415926 müßte der uint-zahl "c0 69 0f db" entsprechen. mit zahl & 7ffff bekommst du die normierte Mantisse mit 23 Binärstellen Ähnlich kannst du dir den Exponenten holen, die Mantisse entsprechend mit einer 1 an 24.Stelle auffüllen(Hidden-bit) und mit dem Exponenten verschieben. Vielleicht noch ein kleiner Tipp- Teile die Funktion doch in Unterfunktionen, die jeweils eine Tätigkeit dürchführen- das arbeitet sich nach meiner Erfahrung besser. LG André Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.