Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 16

Thema: C: umwandlung eines double zu string

  1. #1
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18

    C: umwandlung eines double zu string

    hallo!
    also ich will die quersumme einer ganzzahligen double zahl bilden.
    dazu wollte ich die zahl per sprintf() in einen string schreiben, um dann die einzelnen felder des arrays zu addieren:

    Code:
    sprintf(facstr,"%.0f",faculty);
    wenn ich mir jetzt allerdings die felder des arrays ausgeben lasse, so entsprechen die nicht den einzelnen stellen der zahl.
    was stimmt da nicht?

    grüße!

  2. #2
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Hallo,

    an deinem sprintf-Aufruf kann ich keinen Fehler erkennen, wie erfolgt denn die Ausgabe der einzelnen Feldelemente?
    Übrigens sollte man statt sprintf snprintf verwenden.

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

  3. #3
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von ContainerDriver Beitrag anzeigen
    Hallo,

    an deinem sprintf-Aufruf kann ich keinen Fehler erkennen, wie erfolgt denn die Ausgabe der einzelnen Feldelemente?
    Übrigens sollte man statt sprintf snprintf verwenden.

    Gruß, Florian
    nunja, es scheint ein codierungs-problem zu sein, da die ausgaben die jeweilige ziffer + 48 ist, so ist zb die ausgabe "51" wenn die zahl 3 ist...
    das ließe sich ja ohne probleme lösen, als zahl = (facstr[i] - 48), allerdings kommen nach der gesamten eingelesenen zahl auch noch einige nullen und negative werte vor, obwohl ich ja extra durch %.0f keine dezimalen angegeben habe?

    was ist das denn für eine codierung? ascii ist es zumindest nicht...

  4. #4
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Zeig doch mal bitte den Code für die Ausgabe. Vielleicht hast du bei printf ein %d statt %c stehen?
    Ein gebrechlich Wesen ist der X-Server.

  5. #5
    Registrierter Benutzer Avatar von BLUESCREEN3D
    Registriert seit
    08.11.2002
    Beiträge
    665
    Es ist ASCII. Dabei ist dem Zeichen 0 der Wert 0x30, also genau 48 zugeordnet. Zur Umrechnung müsstest du also nur von jedem Zeichen '0' abziehen ('0' entspricht wiederum 48).

    Du kannst dein Array auch erstmal normal ausgeben, um zu sehen, was drinsteht:
    Code:
    puts(facstr);
    Eigentlich sollten nur die Werte von '0' bis '9', also von 48 bis 57 auftreten und natürlich am Ende der Zahl eine 0 als Abschluss des Strings (dahinter kommen dann zufällige Zahlen - vllt. hast du die mit angeguckt?).

  6. #6
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von ContainerDriver Beitrag anzeigen
    Zeig doch mal bitte den Code für die Ausgabe. Vielleicht hast du bei printf ein %d statt %c stehen?
    hier:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main() {
            int i = 100;
            double faculty = 1;
            char facstr[200];
            int facsum = 0;
            while(i != 0) {
                    faculty *= i;
                    i--;
            }
            printf("faculty:\n\a %.0f\n", faculty);
            sprintf(facstr,"%.0f",faculty);
            for(i=0; i <= strlen(facstr); i++) {
                    facsum += (facstr[i] - 48);
            }
            printf("\nsum: %i\n", facsum);
            exit(0);
    }
    wie gesagt, funktioniert so noch nicht, da ich nach der letzten stelle des double-wertes nullen und negative werte bekomme, von denen ich nicht weiß, woher sie kommen, da der string da ja auch zuende sein sollte....

  7. #7
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Du darfst nur bis
    Code:
    i < strlen(facstr)
    gehen, dann sollte das passen. Und in dem char-Array facstr stehen die ASCII-Entsprechungen der Zahlen drinnen, deshalb musst du -48 rechnen.

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

  8. #8
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von BLUESCREEN3D Beitrag anzeigen
    Es ist ASCII. Dabei ist dem Zeichen 0 der Wert 0x30, also genau 48 zugeordnet. Zur Umrechnung müsstest du also nur von jedem Zeichen '0' abziehen ('0' entspricht wiederum 48).

    Du kannst dein Array auch erstmal normal ausgeben, um zu sehen, was drinsteht:
    Code:
    puts(facstr);
    Eigentlich sollten nur die Werte von '0' bis '9', also von 48 bis 57 auftreten und natürlich am Ende der Zahl eine 0 als Abschluss des Strings (dahinter kommen dann zufällige Zahlen - vllt. hast du die mit angeguckt?).
    jo stimmt so, die ausgabe ist:

    faculty:
    93326215443944175354307254139643190247129328132295 86249193587911066934332573417836828282261870723446 77172798475375489567024353622789607535394918603356 88679424
    57 51 51 50 54 50 49 53 52 52 51 57 52 52 49 55 53 51 53 52 51 48 55 50 53 52 49 51 57 54 52 51 49 57 48 50 52 55 49 50 57 51 50 56 49 51 50 50 57 53 56 54 50 52 57 49 57 51 53 56 55 57 49 49 48 54 54 57 51 52 51 51 50 53 55 51 52 49 55 56 51 54 56 50 56 50 56 50 50 54 49 56 55 48 55 50 51 52 52 54 55 55 49 55 50 55 57 56 52 55 53 51 55 53 52 56 57 53 54 55 48 50 52 51 53 51 54 50 50 55 56 57 54 48 55 53 51 53 51 57 52 57 49 56 54 48 51 51 53 54 56 56 54 55 57 52 50 52
    sum: 734

    mit der bedingung zur ausgabe bzw addition: i < strlen(facstr)...

    problem: irgendwas habe ich übersehen, ergebnis von 734 stimmt nicht!

    aber denke mein eigentliches problem ist gelöst!
    bzw. gibt es eine möglichkeit so einen string sozusagen von ascii zu ganz normalen int werten umzuwandeln? (klar, mt ner schleife, die alle durchgeht und 48 abzieht, aber das is ja nich der perfekte weg)...

  9. #9
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Das falsche Ergebnis kommt wohl daher, weil faculty eine Fließkommazahl ist. Wenn du jetzt z.B. 48 Bit für die Mantisse hast, dann wird die Zahl ab 2^48 - 1 ungenau. Durch den Exponenten kannst du zwar Zahlen größer als 2^48 - 1 darstellen, die hinteren Stellen müssen aber nicht richtig sein.

    EDIT:
    Zitat Zitat von xzm
    bzw. gibt es eine möglichkeit so einen string sozusagen von ascii zu ganz normalen int werten umzuwandeln? (klar, mt ner schleife, die alle durchgeht und 48 abzieht, aber das is ja nich der perfekte weg)...
    Dafür kann man atoi (=ascii to integer) verwenden.
    Geändert von ContainerDriver (05-04-2008 um 18:23 Uhr)
    Ein gebrechlich Wesen ist der X-Server.

  10. #10
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von ContainerDriver Beitrag anzeigen
    Das falsche Ergebnis kommt wohl daher, weil faculty eine Fließkommazahl ist. Wenn du jetzt z.B. 48 Bit für die Mantisse hast, dann wird die Zahl ab 2^48 - 1 ungenau. Durch den Exponenten kannst du zwar Zahlen größer als 2^48 - 1 darstellen, die hinteren Stellen müssen aber nicht richtig sein.

    EDIT:

    Dafür kann man atoi (=ascii to integer) verwenden.
    hum, doof, wie kann ich das denn vehindern?

    EDIT: hab schon long double probiert, ist aber immernoch nich das richtige ergebnis...
    Geändert von xzm (05-04-2008 um 19:37 Uhr)

  11. #11
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main() {
            int i = 100;
            unsigned long long faculty = 1;
            char facstr[200];
            int facsum = 0;
            while(i != 0) {
                    faculty *= i;
                    i--;
            }
            printf("faculty:\n\a %llu\n", faculty);
            sprintf(facstr,"%llu",faculty);
            for(i=0; i < strlen(facstr); i++) {
                    printf("%i ", facstr[i]);
            }
            for(i=0; i < strlen(facstr); i++) {
                    facsum += facstr[i]-48;
            }
            printf("\nsum: %i\n", facsum);
            exit(0);
    }
    unsigned long long will nich, genausowenig wie nur long long...

    beides mal:

    Code:
    $ ./prob20 
    faculty:
     0
    48 
    sum: 0
    woran liegt das denn schon wieder? o_O

  12. #12
    Registrierter Benutzer Avatar von BLUESCREEN3D
    Registriert seit
    08.11.2002
    Beiträge
    665
    Zitat Zitat von xzm Beitrag anzeigen
    unsigned long long will nich, genausowenig wie nur long long...
    (...)
    woran liegt das denn schon wieder? o_O
    Die Zahl "100 Fakultät" hat über 105 Stellen. unsigned long long geht aber nur bis 18446744073709551615. Das reicht also bei weitem nicht.
    Um 100! binär darzustellen bräuchtest du ceil(log(factorial(100))/log(2)) = 525 Bit. Und in C ist (unsigned) long long mit 64 Bit der größte Integer-Datentyp.
    Und genau das ist vermutlich der Sinn der Aufgabe: Du sollst an die Grenzen einiger Programmiersprachen kommen.
    Gleitkommazahlen sind bei großen Werten ungenau, deshalb kannst du die hier nicht benutzen.
    Also:

    Möglichkeit 1:
    Du überlegst dir selbst einen Datentyp für große Zahlen (z.B. ein char-Array) und schreibst dazu Operator-Funktionen (du brauchst nur Multiplikation).

    Möglichkeit 2:
    Du benutzt eine Library für große Zahlen, z.B. GMP.

    Bei 1 musst du "viel" programmieren, bei 2 viel Doku lesen. Da du C lernen willst, solltest du beides mal machen.
    Kleiner Tipp: Du kannst bei Möglichkeit 1 die Multiplikation durch wiederholte Additionen simulieren - das reicht für deine Zwecke völlig und Addition ist einfacher zu Programmieren als Multiplikation.

  13. #13
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von BLUESCREEN3D Beitrag anzeigen
    Die Zahl "100 Fakultät" hat über 105 Stellen. unsigned long long geht aber nur bis 18446744073709551615. Das reicht also bei weitem nicht.
    Um 100! binär darzustellen bräuchtest du ceil(log(factorial(100))/log(2)) = 525 Bit. Und in C ist (unsigned) long long mit 64 Bit der größte Integer-Datentyp.
    Und genau das ist vermutlich der Sinn der Aufgabe: Du sollst an die Grenzen einiger Programmiersprachen kommen.
    Gleitkommazahlen sind bei großen Werten ungenau, deshalb kannst du die hier nicht benutzen.
    Also:

    Möglichkeit 1:
    Du überlegst dir selbst einen Datentyp für große Zahlen (z.B. ein char-Array) und schreibst dazu Operator-Funktionen (du brauchst nur Multiplikation).

    Möglichkeit 2:
    Du benutzt eine Library für große Zahlen, z.B. GMP.

    Bei 1 musst du "viel" programmieren, bei 2 viel Doku lesen. Da du C lernen willst, solltest du beides mal machen.
    Kleiner Tipp: Du kannst bei Möglichkeit 1 die Multiplikation durch wiederholte Additionen simulieren - das reicht für deine Zwecke völlig und Addition ist einfacher zu Programmieren als Multiplikation.
    mhh, dann werde ich das mal probieren. komisch dachte unsigned long long sollte reichen, da es ja 2 * 64bit (128 bit) sind, und das ja einem wert von 2 * 8byte entspricht... da double auch 8 byte hat, dachte ich, sollte es reichen... falsch gedacht...

    PS: funktioniert eigentlich eine zuweisung ala array[i+1] ?
    dann könnte man ja eine funktion schreiben die per for schleife den array wert multipliziert (bzw n-mal addiert) und prüfen ob array[i] > 9 ist, und falls das ist array[i+1] um eins erhöhen (übertrag sozusagen).

  14. #14
    Registrierter Benutzer
    Registriert seit
    28.08.2002
    Beiträge
    496
    unsigned long long ist bei einem 32bit rechner nicht 128 bit groß... würde auf 32 bit rechner sonst extrem aufwändig werden:
    http://de.wikipedia.org/wiki/C99
    Code:
    Datentypen long long int und unsigned long long int, die mindestens 64 Bit groß sein müssen; boolescher Datentyp _Bool; Datentyp _Complex zur Behandlung komplexer Zahlen

  15. #15
    Registrierter Benutzer
    Registriert seit
    01.04.2008
    Beiträge
    18
    Zitat Zitat von quinte17 Beitrag anzeigen
    unsigned long long ist bei einem 32bit rechner nicht 128 bit groß... würde auf 32 bit rechner sonst extrem aufwändig werden:
    http://de.wikipedia.org/wiki/C99
    Code:
    Datentypen long long int und unsigned long long int, die mindestens 64 Bit groß sein müssen; boolescher Datentyp _Bool; Datentyp _Complex zur Behandlung komplexer Zahlen
    jojo, meinte ja auch das es 8byte => 64bit sind.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •