www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik unsigned long --> float


Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein math. Problem:

vier Variable sind definiert. (für ATmega128)

unsigned long al = 10034456;
unsigned long bl = 1254299;
float af;
float bf;

// Die Umwandlung soll hier geschehen:

af = al;
bf = bl;

// Das Ergebniss ist nicht ganz optimal.
// In af steht der Wert 1,00345E+7,
// und in bf steht 1,2543E+6

// Der C-Compiler CodeVision rechnet nur mit max. 5-stelliger
// Genauigkeit.

Kennt jemand eine Möglichkeit diese Einschränkung zu umgehen?

Vielen Dank    Norbert

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielleicht nur ein Darstellungsproblem der float Zahl? Code-Vision 
arbeitet (wie alle anderen Compiler auch die ich kenne) mit 23bit 
Mantisse.

Autor: dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
entweder mit long rechnen und am Ende der
Berechung den Nachkommateil errechnen.
Also vor dem Rechnen mit 1000 erweitern und nach der
Berechnung wieder durch 1000 teilen.

Eine weite Möglichkeit ist die Verwendung von double,
aber das ist evtl. mit dem Compiler nicht möglich.
Selbst wenn alles kompiliert, kann es passieren, das immer noch float 
verwendet wird.
Also immer noch 16-Bit.

Dieter

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

float läßt sich fast immer verhindern. Ich sehe keinen Sinn darin auf 
8-Bit Maschinen mit float zu hantieren. Selbst auf dem M16C vermeide ich 
das wo es geht. Meist rechnet es sich genausogut nur schneller mit int 
bzw. long.

Matthias

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Norbert,
letzlich wird Dir nicht der interne float-Wert angezeigt, sondern das, 
was printf daraus macht. Bei float ist die 7. Dezimalstelle ungenau, 
sechs Stellen sollten stimmen. Bei 1.2543E+6 wird m.E. nur eine '0' beim 
Formatieren unterdrückt, nachdem zuvor die letzte '9' richtig gerundet 
wurde. Ich sehe insgesamt keinen Mangel bei Deinen floats.

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte mein Problem etwas verdeutlichen:

meine Variablen sind:

unsigned long al = 10034456;
unsigned long bl = 1254299;
float af;
float bf;

Wenn ich die Division der Zahlenwerte von al / bl mit dem Taschenrechner 
ausrechne, so bekomme ich das Ergebniss 8,000051...

Wird jedoch die Division der float-Werte af / bf im Controller
durchgeführt, so bekomme ich das Ergebniss 8,000079...
Dieses Ergebniss ist nicht brauchbar. Ich benötige eine Berechnung mit 
6-stelliger Genauigkeit(ANSI-C-Standart).

Mein Compiler(CodeVision), und alle anderen AVR-Compiler machen bei 
float-Berechnungen nur 5-Stellen genau.

Im weiteren Verlauf des Programmes werden die  Berechnungen

periode = 8,000079 * 1e-7 und frequenz = 1 / periode durchgeführt.


Vielleicht finde ich einen Weg, die von Dieter und Matthias 
vorgeschlagene long-Berechnung durchzuführen.


Schönen Gruß   Norbert

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Norbert,

ich habe testweise mal Deine Berechnung auf nem 8051 laufen lassen:

unsigned long test( unsigned long a, unsigned long b )
{
  float af, bf;
  af = a;
  bf = b;

  return  af / bf * 1e8;
}


void main( void )
{
  unsigned long al = 10034456;
  unsigned long bl = 1254299;

  al = test( al, bl );
  for(;;);
}

Da kommt als Ergebnis richtig 800005120 raus.
Warum alle AVR-Compiler das nicht können sollen, ist mir unverständlich.

Da bleibt wohl nur, es in Assembler zu machen. Da kannst Du ganz leicht 
beliebig genaue Ganzzahldivisionen nach der üblichen 
Schieben-Testen-Abziehen-Methode machen.
Ich habs z.B. mal für einen Frequenzzähler mit 56 Bit / 24 Bit gemacht 
(siehe Anhang).


Peter

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei solchen Problemen werde ich immer neugierig: ein Turbo-C Compiler 
aus der 'Steinzeit' liefert mir Dein Taschenrechnerergebnis; ein 
C-Compiler einer Firma mit drei Buchstaben, die mit 'I' anfängt, liefert 
mir ebenfalls die 8.000051. Zumindest von WinAvr würde ich auch ein 
korrektes Ergebnis erwarten.

Deine Berechnungen mit long zu machen ist kippsch bezüglich eines großen 
Meßbereiches - float erleichtert dies erheblich. Falls Du nur 
Frequenz/Periode messen möchtest, nutzt Dir vielleicht 
www.mino-elektronik.de/fmeter/fm_software.htm. Dort findest Du .c-Quelle 
+ .hex-Code allerdings für einen 2313.

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael: Sicherlich gibt es Compiler die das gewünschte Ergebniss 
liefern. Aber weder die 'Steinzeitcompiler' noch der IAR ünterstützten 
den AVRmega128!

Für mich entwickelt sich das Ganze zur Farce. Da bietet mir der mega128 
die optimale on-Board Hardware, wegen fehlender
SW-Tools kann ich ihn aber nicht einsetzen.

Als Alternative bleibt mir nur der C166-Compiler von Keil. Denn als 
Controllerersatz für den m128 kann ich nur den XC161CJ von Infineon 
einsetzen.

Heul...


Trotzdem, danke für Eure Meinung!    Norbert

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Norbert,
der IAR-Compiler unterstützt den 128 voll (V2.xx). Auch die Version 1.xx 
erzeugt Code dafür, ohne allerdings die neuen Befehle zu nutzen. Die 
Tage hatte ich hier auch die Zeiten für fmul/fdiv mit unter 50us bei 
12MHz angegeben, was einige Gemüter vor 'Erstaunen' aufregte. Das Teil 
kostet aber richtig Kohle.
Wenn der C166 für Dich keine Probleme bereitet, nutze ihn.
Zuvor würde ich aber unbedingt WinAvr testen, der auch korrekt rechnen 
müßte. Frag doch 'mal im Forum AVR-GCC nach der Rechengenauigkeit; da 
wirst Du sicherlich kompetente Leute finden, die Dein Beispiel 'mal eben 
schnell' rechnen lassen können.

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael,

laut IAR.com wird der mega128 nicht von Workbench unterstützt.

Da ich eh die komplette C166-Umgebung von Keil (µVision2) besitze würde 
es wenig Sinn machen noch einmal eine sehr teure IDE zu kaufen.

Was WinAvr betrifft, so ist es merkwürdig still hier im Forum.
Ich gehe davon aus, daß User des AVR-GCC-Forum hier im Allgemein-Forum 
auch mal 'Querlesen'.


Schönen Gruß     Norbert

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.