Forum: Compiler & IDEs pow() unter GCC


von werN92 (Gast)


Angehängte Dateien:

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

von ... (Gast)


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.

von ... (Gast)


Lesenswert?

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
}

von werN92 (Gast)


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

von werN92 (Gast)


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

von ... (Gast)


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):
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 :)

von werN92 (Gast)


Lesenswert?

Hallo

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

mfg

von Karl H. (kbuchegg)


Lesenswert?

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?

von werN92 (Gast)


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

von Karl H. (kbuchegg)


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.

von werN92 (Gast)


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

von Karl H. (kbuchegg)


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)

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
Noch kein Account? Hier anmelden.