Arduino: double test = pow((float)20.0,(float)10.0) kein sinnvolles Ergebnis?

Gast #4842248
Lesenswert?
• ▲
▼
Hallo,

ich ärgere mich seit einigen Tagen mot pow() herum:


Führe ich das mit 20.0^5.0 aus:
double test = pow((float)20.0,(float)10.0)
Dann ist das Ergebnis korrekt:

0x0030D400
3200000.00


Führe ich das mit 20.0^10.0 aus:
double test = pow((float)20.0,(float)10.0)
Dann ist das Ergebnis Falsch:

FFFFFFFF
ovf


Eigentlich ist der float Wertebereich(double ist bei den 8Bit AVR's 
gleich) bis 3.403E+38, 20^10 (1.024E+13 ) passt also locker rein.

Was geht da ab, was mache ich falsch?

Vielen Dank,

Grüße

Seppel
Gast #4842314
Lesenswert?
• ▲
▼
Hallo Seppel,

ich glaube, da liegt ein Missverständnis vor.
Mit "(uint32_t) test" wird der Floating-Point-Wert in einen Integer 
umgewandelt und nicht nur als Integer interpretiert.
Entsprechend dem von dir verlinkten Tool möchtest du folgendes 
erreichen:

Serial.println(*reinterpret_cast<uint32_t*>&test, HEX);

Viele Grüße,
Marcel
Gast #4842393
Lesenswert?
• ▲
▼
Hallo,

hab's mit einem pointer gelöst, nicht schön(ja richtig böse),... aber 
geht auch.

----------------------------------------------------------------------

Ich hab folgendes probiert:

  float mytest2 = 1.024E13;
  uint32_t* oh = (uint32_t*)&mytest2;
  Serial.println("Test2");
  Serial.println((uint32_t)*oh,HEX);

Das Ergebnis ist:

Test2
551502F9

-------------------------------------

Also, wie zu erwarten war, float (IEEE754) kann 1.024E13 darstellen, das 
ist schon mal gut dass das klappt.



----------------------------------------------------------------------

Da ich nur ganzzahlige Exponenten brauche hab ich mir eine Funktion 
selbst geschrieben:

double myPow (double base, uint8_t exponent)
{
  uint8_t iter = (exponent-1U);
  double result = base;
   for ( ; (iter>0) ; (iter=iter-1) )
   {
     result = (result * base);
   }
   return result;
}

-------------------------------------
Geht immer noch nicht. Wahrscheinlich liegt das daran dass mit 
steigendem Iterator eine große mit einer kleinen Zahl multipliziert wird 
und dann die Ungenauigkeiten ein sinnvolles Ergebnis verhindern, sicher 
bin ich aber nicht.

----------------------------------------------------------------------

Hat jemand eine Idee wie ich das läsen kann?

Vielen Dank,

Grüße

Seppel
Gast #4842399
Lesenswert?
• ▲
▼
Seppel schrieb:
> Hat jemand eine Idee wie ich das läsen kann?

was ist das genau Problem? Willst du einen Rechnen per Seriell 
programmieren oder hat da ganze auch einen Zweck?

Es mag ja Anwendungen geben, wo man so große Zahlen fast ohne 
Genauigkeit braucht, aber mir ist bis jetzt keine untergekommen.
Gast #4842411
Lesenswert?
• ▲
▼
P.S.

Und jetzt kommt der Knaller:

double myPow10 (double base)
{
  return (
    (((base*base)*(base*base))*((base*base)*(base*base)*(base*base)))
    );
}

Es geht,....

Kann mir jemand erklären was da schief läuft wenn man das mit einer for 
Loop macht?

Vielen Dank,

Grüße

Seppel
Gast #4842497
Lesenswert?
• ▲
▼
Hallo Dirk,

Mit der von mir geschriebenen "Hard Coded" 20.0^10 funktioniert es, mit 
pow nicht. Ich weiß auch nicht was Du mit "Meist weiß der Compiler 
selber besser, wann er pow ersetzen kann." meinst.

Und nein, in der Applikation sind die Exponenten nicht konstant, nur 
ganzzahlig.

Grüße

Seppel
Gast #4842529
Lesenswert?
• ▲
▼
Seppel schrieb:
> hab's mit einem pointer gelöst, nicht schön(ja richtig böse),... aber
> geht auch.

Das nennt sich Pointer Type Punning und ist undefiniertes Verhalten, 
weil es zugleich auch Pointer Aliasing ist. Kann gehen, kann auch 
jederzeit nicht gehen. Type Punning würde ich über eine Union machen.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.