www.mikrocontroller.net

Forum: Compiler & IDEs pow() unter GCC


Autor: werN92 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ich grad gute Laune hab.
Versuchs mal damit (ungetestet):
#include <stdint.h>

uint64_t binToDez(unsigned char *field, unsigned int size)
{
  uint64_t value = 0;
  unsigned int index;

  if(size > 64) {
    // ERROR
    return 0;
  }
  index = size;
  while(index) {
    index--;
    value <<= 1;
    if(field[index]) {
      value |= 0x01;
    }
  }
  return value;
}

Autor: werN92 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: werN92 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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):
#include <stdint.h>

uint64_t binToDez(uint8_t *field, uint8_t size)
{
  uint64_t value = 0;
  if(size <= 64) while(size) value = (value << 1) | field[--size];
  return value;
}

Für '0'/'1' und umgedrehte Reihenfolge dann etwa so:
#include <stdint.h>

uint64_t binToDez(char *field, uint8_t size)
{
  uint64_t value = 0;
  if(size <= 64) for(uint8_t i = 0; i < size; i++) value = (value << 1) | (field[i] - '0');
  return value;
}

Ansonsten auch: http://www.google.de/search?q=strtoul+source+code :)

Autor: werN92 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Die untere deiner Versionen funktioniert, danke. Jetzt müsstest du mir 
nur noch den Code ein wenig erläutern.

mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
werN92 schrieb:
> Hallo
>
> Die untere deiner Versionen funktioniert, danke. Jetzt müsstest du mir
> nur noch den Code ein wenig erläutern.

Hinweis:
   value = (value << 1) | (field[i] - '0');
könnte man auch so schreiben
   value = 2 * value;
   if( field[i] != '0' );
     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
zahl = 0
erstes Zeichen '5'     zahl = 10 * zahl = 10 *   0 ->    0;  plus 5    -> zahl = 5
nächstes Zeichen '8'   zahl = 10 * zahl = 10 *   5 ->   50;  plus 8    -> zahl = 58
nächstes Zeichen '7'   zahl = 10 * zahl = 10 *  58 ->  580;  plus 7    -> zahl = 587
nächstes Zeichen '3'   zahl = 10 * zahl = 10 * 587 -> 5870;  plus 3    -> zahl = 5873

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?

Autor: werN92 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: werN92 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.