[Erledigt] Zeiger(einzelne bits einer double ausgeben)



  • Was denn nun, Bits oder Bytes oder Bits der Bytes?
    Auch war in der Aufgabenstellung nicht von einem Zeiger auf double die Rede, den du aber implementierst.



  • Ist die Mantisse nicht immer implizit 1. ... D.h. fuer 1.0 sollte da 00000... stehen.

    Ok, genauer hingesehen:

    int a = *d;
    

    Hier tritt eine automatische Umwandlung auf von double nach int . Die macht alles kaputt. Naechster Fehler: Auf meinem System, Windows 7 64 Bit, unter VS 11 Beta ist int nur 4 Byte gross.



  • @Wutz Wir sollen Zeiger verwenden, hat der Professor gesagt.

    Wegen den bits und bytes:

    Wir sollen alle bits einer double variable ausgeben, also
    bei einer double größe von 8 byte (mein OS) muss ich 64 bit's
    ausgeben.

    Der Prof. hat den tip gegeben, da ja alle double Adressen( 8 byte = 8 Adressen)
    nebeneinander liegen, sollen wir die erste adresse nehmen und dessen 8 bits
    ausgeben, danach zur nächsten adresse springen und diese bits ausgeben usw.
    (je nach double größe).

    @knivil
    das könnte das problem sein, ich will ja eig nur den teil der double von einer
    adresse in das int "stopfen" und danach die nächsten bits der folgenden adresse

    mfg



  • Dann schreibe doch erstmal eine Funktion, die die Bits eines Bytes ausgibt. Normalerweise ist char oder unsigned char 8 Bit (1 Byte hier) gross. Dann sehen wir weiter. Darueber hinaus ist double auch auf einem 32 Bit System meist 64 Bit gross.



  • @knivil

    die Funktion gibt mir die bits eines chars aus:

    void displayBits(char z) {
        char i =1;
        for(i;i<7;i++) {
            if(z & (1 << i)) printf("1");
            else printf("0");
        }
    
    }
    
    z=12  => 011000
    z=27  => 101100
    

    Hoffe hab es richtig verstanden.

    Das müsste ich nach byte anzahl einer double wiederholen, um alle bytes einer
    double auszugeben. So wie ich es verstehe. Also müsste ich dies doch für jede
    Adresse der double machen ?
    Nur versteh ich nicht, wie man nur die bits der einen Adresse bekommt und
    nicht die ganze double Variable

    (Ich hoffe ich schreibe nicht zu verwierend)

    mfg



  • Die Größe von double hat nichts mit der Adressbreite des Systems zu tun.

    C ist so intelligent, das du beim Zeiger weiterzählen nicht wissen musst, wie groß ein double ist.

    Das a = *d; mag bei der Definition noch das machen was du vorhast.
    Als Zuweisung macht es aber etwas anderes.
    Zum 1.: ein Zeiger ist kein int.
    Zum 2.: durch den Dereferenzierungsoperator bekommst du den Wert auf den der Zeiger zeigt.
    Dieser Wert wird dann in ein int gewandelt.

    Die Größe einer Variablen/Types bekommst du mit sizeeof()
    Also nimm statt <=7 ein `< sizeof(double)

    `

    unsigned char *pc;
    pc = (char *)d;
    
    for(j=0;j<sizeof(double);j++,pc++)
      printf("%02x ", *pc);
    putchar("\n");
    

    Ein Byte hat aber so um die 8 Bit (nicht 6). Für den Wert solltest du CHAR_BIT aus <limits.h> nehmen.



  • void displayDoubleByte( double d )
    {
    	unsigned char *p = (unsigned char*) &d;
    	size_t i = 0;
    	for( ; p < (unsigned char*) &d + sizeof( double ); ++p ) {
    		for( i = CHAR_BIT; i > 0; --i ) {
    			printf( "%c", (*p & 1 << ( i - 1 ) ) ? '1' : '0' );
    		}
    		printf( " " );
    	}
    	printf( "\n" );
    }
    

    Ihr dürft mich jetzt steinigen.



  • Jaja, zu schnell abgeschickt. Der cast muss bei mir natürlich auch pc = (unsigned char *)d; sein.
    Obwohl, uint8_t wäre noch besser.



  • @DirkB

    Danke für deine Hilfe

    meine Code jetzt:

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    
    /*
     * 
     */
    
    void displayDoubleByte(double *d);
    
    int main(int argc, char** argv) {
    
        double zahl = 1.0;
    
        displayDoubleByte(&zahl);
    
        return (EXIT_SUCCESS);
    }
    
    void displayDoubleByte(double *d) {
    
        unsigned char *pc;
        pc = (char *)d;
    
        for(int j=0;j<sizeof(double);j++,pc++) {
            //printf("%02x ", *pc);
            for(int i = 0; i<=CHAR_BIT; i++) {
                if(*pc & (1 << i)) printf("1");
                else printf("0");
            }
            printf(" ");
        }    
    }
    

    Die Zeiger werd ich mir noche ein bisschen anschauen müssen.

    Edit:
    @ Swordfish steinigen wird dich hoffe ich keiner 😉

    Nur bringen fertige Lösungen nicht viel fürs Lernen.
    Ich hab noch viel vor mir...

    mfg



  • DirkB schrieb:

    Die Größe von double hat nichts mit der Adressbreite des Systems zu tun.

    Na, der Prof. meint das wahrscheinlich anders. Double besteht aus 8 einzeln addressierbaren Einheiten/Bytes.

    (Ich hoffe ich schreibe nicht zu verwierend)

    Doch tust du.

    Nur versteh ich nicht, wie man nur die bits der einen Adresse bekommt

    Bytes ... und nicht der Adresse, sondern des Speichers, auf den durch die Adresse verwiesen wird.

    011000

    Fuer 8 Bit sind das etwas wenig.

    Dann ist die kleinste addressierbare Einheit ist ein Byte, meist durch char oder unsigned char repraesentiert. D.h. du musst deinen Zeiger auf double nach Zeiger auf char konvertieren, um auf die einzelnen Bytes eines 8 Byte Speicherbereiches zuzugreifen.

    unsigned char* c = (unsigned char*)(&d);
    

    Und danach fuer jeden Wert deine Funktion displayBits aufrufen.

    displayBits(c[7]);
    displayBits(c[6]);
    displayBits(c[5]);
    displayBits(c[4]);
    displayBits(c[3]);
    displayBits(c[2]);
    displayBits(c[1]);
    displayBits(c[0]);
    


  • Die 6 bits Ausgabe, war mein Fehler im Eifer des Gefechts, sollte
    Eigentlich von o bis <=7 sein.

    Ich danke euch auf jeden Fall für die schnelle Hilfe!

    mfg rufrider und schönen Abend noch.



  • rufrider schrieb:

    Eigentlich von o bis <=7 sein.

    Hoffentlich hat dann auch o den Wert 0 😃

    Gewöhn dir lieber die C-Schreibweise < 8 an.
    Dann siehst du dass es 8 Durchläufe sind (wenn du bei 0 anfängst)



  • rufrider schrieb:

    Schreiben Sie eine Funktion displayDoubleBytes(double d), die alle Bytes ausgibt,

    rufrider schrieb:

    Wir sollen Zeiger verwenden, hat der Professor gesagt.

    Entweder dein Professor hat keine Ahnung oder du kannst nicht richtig lesen und schreiben oder beides.
    Beide o.g. Aussagen widersprechen sich.
    Eine double-Variable ist genau sizeof(double) Bytes und sizeof(double)*CHAR_BIT Bits groß.



  • "Schreiben Sie eine Funktion displayDoubleBytes(double d), die alle Bytes ausgibt," --> so steht es in der PDF des Profs.

    Das mit dem keine Ahnung des Profs glaub ich nicht, leider hat er
    des öfteren Schreibfehler in seinen Texten und Beispielen.

    mfg



  • Du kannst jederzeit einen Zeiger auf deine Variable erhalten, indem du den Adressoperator & auf beispielsweise d anwendest:

    double d = 14.3;
    double* p = &d; // p zeigt auf d
    

Anmelden zum Antworten