Hallo hab in einigen Posts gelesen, dass es mit der pow()- Funktion unter GCC Probleme geben soll. Das könnte ein Grund sein, warum meine Funktion mit pow() nicht richtig läuft, ein Fehler meinerseits ist natürlich auch nicht ausgeschlossen. Die Funktion soll ein Feld von 0 und 1 übergeben bekommen und den Dezimalwert berechnen. Klingt einfach, möge man meinen. Hab ich mir auch gedacht, bis die Funktion Blödsinn zurücklieferte, und das in allen möglichen Konstellationen. Der Code ist im Anhang, math.h ist eingefügt. Grundlegendes Problem ist, dass der errechnete Dezimalwert immer 1 oder 2 unter dem Sollwert liegt und sobald die Feldgröße 8 übersteigt, ändert sich nichts mehr, der Wert bleibt bei 254 stehen. mfg
Autsch. Deine Funktion rundet sich zu Tode. Dieses ganze Hinundhergecaste von int zu double und zurück ist einfach nur eine Katastrophe. Schmeiß die Funktion samt double komplett weg und schreib sie neu. Diesmal aber ohne double, dann rechnet sie eventuell auch richtig. Falls Du das Rad nicht zum zweiten Mal erfinden willst, kannst Du Dir natürlich auch mal die Funktion strtol bzw. strtoul anschauen.
Weil ich grad gute Laune hab. Versuchs mal damit (ungetestet):
1 | #include <stdint.h> |
2 | |
3 | uint64_t binToDez(unsigned char *field, unsigned int size) |
4 | {
|
5 | uint64_t value = 0; |
6 | unsigned int index; |
7 | |
8 | if(size > 64) { |
9 | // ERROR
|
10 | return 0; |
11 | }
|
12 | index = size; |
13 | while(index) { |
14 | index--; |
15 | value <<= 1; |
16 | if(field[index]) { |
17 | value |= 0x01; |
18 | }
|
19 | }
|
20 | return value; |
21 | }
|
Ja, ich habe die Funktion vorher komplett mit int ausgeführt und auch da gabs Fehler. Das war eigentlich der Grund, warum ich mit dem "Gecaste" begonnen habe. Aber die anderen beiden Funktionen werd ich mir mal anschauen. mfg
Kann jetzt den Code gerade nicht probieren, aber eine Frage: Hätte atoi nicht die gleiche Wirkung wie strtol? Weil das Problem ist folgendes: Ich müsste den errechneten Dezimalwert des Feldes auf den UART und ein LCD ausgeben und muss dazu ja die Funktion itoa verwenden. Im Prinzip würde ich dann zuerst das Feld in int umrechnen und im nächsten Schritt rechne ich den int- Wert wieder in einen String zurück. Ist das ein falscher Ansatz? mfg
Nein, da atoi immer mit Basis 10 arbeitet. Bei strtol kann man die Basis angeben (in Deinem Fall 2). Außerdem kann man bei letzterer auch noch leichter auf Fehler Überprüfen. Für beide Funktionen müßten die Ausgangsdaten aber als String vorliegen (inclusive abschließender '\0'). Also '0' und '1' als Character in Deinem Feld. Außerdem ist dann vermutlich die Reihenfolge verkehrt (LSB und MSB vertauscht). Laut Deiner Beschreibung und Deinem Code liegen sie aber als Zahlen vor (Merke: 0 != '0'). Hier noch ne Kurzversion (auch ungetestet):
1 | #include <stdint.h> |
2 | |
3 | uint64_t binToDez(uint8_t *field, uint8_t size) |
4 | {
|
5 | uint64_t value = 0; |
6 | if(size <= 64) while(size) value = (value << 1) | field[--size]; |
7 | return value; |
8 | }
|
Für '0'/'1' und umgedrehte Reihenfolge dann etwa so:
1 | #include <stdint.h> |
2 | |
3 | uint64_t binToDez(char *field, uint8_t size) |
4 | {
|
5 | uint64_t value = 0; |
6 | if(size <= 64) for(uint8_t i = 0; i < size; i++) value = (value << 1) | (field[i] - '0'); |
7 | return value; |
8 | }
|
Ansonsten auch: http://www.google.de/search?q=strtoul+source+code :)
Hallo Die untere deiner Versionen funktioniert, danke. Jetzt müsstest du mir nur noch den Code ein wenig erläutern. mfg
werN92 schrieb: > Hallo > > Die untere deiner Versionen funktioniert, danke. Jetzt müsstest du mir > nur noch den Code ein wenig erläutern. Hinweis:
1 | value = (value << 1) | (field[i] - '0'); |
könnte man auch so schreiben
1 | value = 2 * value; |
2 | if( field[i] != '0' ); |
3 | value = value + 1; |
das obere ist die C typische Kurzform. Das untere ist die für dich wahrscheinlich leichter verständliche Langform. Hinweis 2: Wir bewegen uns im Dezimalsystem. Du kriegs die Zeichenkette '5' '8' '7' '3' (die offensichtlich die Zahl 5873 darstellen soll) Und du rechnest
1 | zahl = 0 |
2 | erstes Zeichen '5' zahl = 10 * zahl = 10 * 0 -> 0; plus 5 -> zahl = 5 |
3 | nächstes Zeichen '8' zahl = 10 * zahl = 10 * 5 -> 50; plus 8 -> zahl = 58 |
4 | nächstes Zeichen '7' zahl = 10 * zahl = 10 * 58 -> 580; plus 7 -> zahl = 587 |
5 | nächstes Zeichen '3' zahl = 10 * zahl = 10 * 587 -> 5870; plus 3 -> zahl = 5873 |
6 | |
7 | es gibt kein nächstes Zeichen mehr. Das Ergebnis der Umwandlung lautet 5873. |
Frage: Warum wohl multiplizere ich hier mit 10? 2. Frage: Was bedeutet das dann für die Umwandlung von Binärzahlen?
Karl heinz Buchegger schrieb: > Frage: Warum wohl multiplizere ich hier mit 10? Weil ich immer eine Zehnerstelle vorrücke. Karl heinz Buchegger schrieb: > 2. Frage: Was bedeutet das dann für die Umwandlung von Binärzahlen? Wenn ich am Feld die Binärzahl '1' '0' '1' '1' stehen habe, siehts wie folgt aus: 10 * 0 + 1 = 1 10 * 1 + 0 = 0 10 * 10 + 1 = 101 10 * 101 + 1 = 1011 Es wird der String in einen int konvertiert. mfg
werN92 schrieb: > Karl heinz Buchegger schrieb: >> Frage: Warum wohl multiplizere ich hier mit 10? > Weil ich immer eine Zehnerstelle vorrücke. Genau. UNd das tun wir warum? Weil wir im Dezimalsystem arbeiten (Dezimalsystem: Zahlensystem zur Basis 10) Im Dezimalsystem etspricht eine Multiplikation mit 10 der Operation: alle Stellen um 1 nach links schieben und eine 0 anhängen. Allgemeiner: In jedem beliebigen Zahlensystem zur Basis b entspricht eine Multiplkation mit b der Operation: alle Stellen um 1 nach links schieben und rechts mit einer 0 auffüllen. > Karl heinz Buchegger schrieb: >> 2. Frage: Was bedeutet das dann für die Umwandlung von Binärzahlen? > Wenn ich am Feld die Binärzahl '1' '0' '1' '1' stehen habe, siehts wie > folgt aus: > 10 * 0 + 1 = 1 > 10 * 1 + 0 = 0 Achso? 10 * 1 + 0 ergibt 0 > 10 * 10 + 1 = 101 > 10 * 101 + 1 = 1011 > Es wird der String in einen int konvertiert. Tja. Warum mulitplizierst du mit 10? Wir sind hier nicht mehr im Dezimalsystem (System zur Basis 10). Wir sind im Binärsystem (Zahlensystem zur Basis 2) Oder wolltest du mich auf die Probe stellen und die 10 mit denen multipliziert wird, sind ebenfalls als Binärzahl aufzufassen. Dann stimmts allerdings. Nur ist das deinem Compiler wieder schnuppe. Für den ist 10 immer eine dezimale 10. Aber: Du willst ja keinen int, der denselben Wert hat wie eine Abfolge von 0 und 1. Also: 1011 (dezimal) für die Abfolge '1' '0' '1' '1'. 1011 hat das Bitmuster 0000001111110011. Und das entspricht noch nicht einmal annähernd dem 'Bitmuster' welches durch '1' '0' '1' '1' eigentlich erzeugt werden sollte.
Karl heinz Buchegger schrieb: > Allgemeiner: In jedem beliebigen Zahlensystem zur Basis b entspricht > eine Multiplkation mit b der Operation: alle Stellen um 1 nach links > schieben und rechts mit einer 0 auffüllen. Genau das hab ich wissen wollen. Danke. Karl heinz Buchegger schrieb: > Achso? > 10 * 1 + 0 ergibt 0 Blödsinn, hab ich mich vertippt. Karl heinz Buchegger schrieb: > Wir sind hier nicht mehr im Dezimalsystem (System zur Basis 10). Wir > sind im Binärsystem (Zahlensystem zur Basis 2) Ok, das ist dann einleuchtender. 2 * 0 + 1 = 1 2 * 1 + 0 = 2 2 * 2 + 1 = 5 2 * 5 + 1 = 11 Jetzt passt´s;-) Karl heinz Buchegger schrieb: > der wolltest du mich auf die Probe stellen und die 10 mit denen > multipliziert wird, sind ebenfalls als Binärzahl aufzufassen. Nein, nein, keine Sorge. mfg
werN92 schrieb: >> der wolltest du mich auf die Probe stellen und die 10 mit denen >> multipliziert wird, sind ebenfalls als Binärzahl aufzufassen. > Nein, nein, keine Sorge. So abwegig ist das gar nicht. Den in jedem belibigen Zahlensystem zur Basis b, ist die Schreibweise für b immer 10 (wobei die Zahl natürlich in diesem Zahlensystem ausgedrückt wird)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.