multiplikation Mal Kommazahl

Gast #873969
Lesenswert?

Hallo Leute,
für die Linearisieurung meiner Hallmessdaten möchte ich folgende 
Gleichung errechnen:
Xsoll= 1,7692*Xist+555,2;
1) der Compiler nimmt es an, und macht keine errors, aber es wird dem 
Xsoll einfach eine "1" zugewiesen,
es heisst er erkennt die Kommazahl etwa nicht!
2) der Offset macht mir schon Verlust meiner Genauigkeit, soll ich den 
einfach wegmachen, oder nehme ich ihn auch in die Gleichung?
Danke im Voraus!
#873990
Lesenswert?

Abderrahim wrote:
> Gleichung errechnen:
> Xsoll= 1,7692*Xist+555,2;
> 1) der Compiler nimmt es an, und macht keine errors, aber es wird dem
> Xsoll einfach eine "1" zugewiesen,

Hallo,

die Schreibweise für "Kommazahlen" in C ist Punkt statt Komma, also:
Xsoll= 1.7692*Xist+555.2;
müsste ein brauchbares Ergebnis liefern, wenn Xsoll als float oder 
double deklariert ist.

Schöne Grüsse,

dl7avf
#874003
Lesenswert?

Abderrahim wrote:
> Hallo Leute,
> für die Linearisieurung meiner Hallmessdaten möchte ich folgende
> Gleichung errechnen:
> Xsoll= 1,7692*Xist+555,2;
> 1) der Compiler nimmt es an, und macht keine errors, aber es wird dem
> Xsoll einfach eine "1" zugewiesen,
> es heisst er erkennt die Kommazahl etwa nicht!

Mit dem Komma handelst du dir wohl ein Problem ein. Schreibe stattdessen 
Xsoll= 1.7692*Xist+555.2;.

Die Tipps der anderen sind natürlich richtig und sauber, aber lösen dein 
Problem nur über Umwege.
Gast #874017
Lesenswert?

> nein, mein Compiler versteht das Komma und kein Punkt als das
> Kommazeichen

Ist der von Microsoft?
Und selbst da kann ich mir das nicht vorstellen.
Schließlich gibt es einen Sprachstandard für C,
der sicherlich schon älter ist als Du.
(Bitte verzeih die Hetze).
Gast #874020
Lesenswert?

bitte kurz mal auf meinem Code schauen:

    val_x = current_value_x;
    val_y = current_value_y;
    //Gleichchung fuer Linearisierung
    Lin_current_value_x = (1,7692*1023)*val_x;


    Lin_current_value_y = 1,7692*val_y ;
Es wurde so kompiliert und zum emulator geschickt!
kann jemand dies vielleicht erklären?
Danke für die nette Hilfe!
Gast #874035
Lesenswert?

Aber bitte mit 1024 multiplizieren, das läuft dann auf einen Shift 
hinaus.


Man muss einfach sein Denken ein wenig umstellen auf binär.

So wie Benedikt oder so ähnlich würde ich es auch machen.


@Benedikt:
Xsoll= ((1.769265536*65536L)*Xist+(555,2*65536L))/65536L;
Hast Du die Konstante 1.76 vergenauert um 5 Stellen?  ;-)


@Abderrahim
Vielleicht könntest Du uns mal verraten, welche Umgebung Du verwendest?
#874039
Lesenswert?

eProfi wrote:
> Aber bitte mit 1024 multiplizieren, das läuft dann auf einen Shift
> hinaus.

Wobei das in diesem Fall egal sein dürfte, wenn nur die Konstante damit 
multipliziert wird. Denn das optimiert ein guter Compiler und 
multipliziert zur Compilezeit.

> @Benedikt:
> Xsoll= ((1.769265536*65536L)*Xist+(555,2*65536L))/65536L;
> Hast Du die Konstante 1.76 vergenauert um 5 Stellen?  ;-)

???
Gast #874045
Lesenswert?

ich benutze einen Freescale CodeWarrior
Wieso soll ich mal 65536 multipl.?
Ich habe bloß eine 10Bit Auflösung keine 16.
Was meinst du mit :
> > Hast Du die Konstante 1.76 vergenauert um 5 Stellen?
Gast #874061
Lesenswert?

habe das probiert:
    Lin_current_value_x = (17692*val_x)/10000;
    Lin_current_value_x = (word)((1,7692*1000)*val_x)/1000;
bekomme das Gleiche Ergebnis!
Mein "Val_x" ist 407, also der "Lin_current_value_x" sollte auf ungefähr
2 langen, bekomme aber 3 wackelnde Werte: 3..30..54
bin total verwirrt!
Kann jemand helfen?
Gast #874064
Lesenswert?

Wenn du mit C arbeitest, kannstu dich aufn Kopf stellen:
1
    Lin_current_value_x = (word)((1,7692*1000)*val_x)/1000;
ist definitiv Käse! Das hat es noch nie im C-Standard gegeben und das 
wird es auch nie geben.

Syntaktisch ist das korrekt, das nennt man KOMMAOPERATOR; gerechnet 
wird aber anders:
1
((1,7692*1000)*val_x)/1000
2
/* ist gleich */
3
(1*val_x)/1000
Gast #874107
Lesenswert?

> Poste mal die Deklarationen der Variablen
word      current_value_x;
word      current_value_y;
word      Lin_current_value_x;
word      Lin_current_value_y;
word      Offset=111;
word      val_x;
word      val_y;

> => 17692 * 407 = 7'200'644 = (uint16) 57219
was heisst hier (7'200'644)?
> (uint16) (17692*407) / 10000  = (57219/10000) = 5
 Leute irgendwie folge ich euch euch nicht mehr,
bin ganz Anfänger im Ding, und da sehe schon solche Komentare:
>Wenn du mit C arbeitest, kannstu dich aufn Kopf stellen:
Das verletzt!
#874139
Lesenswert?

>Swen Pauli hats geschrieben, Kommaoperator.
>Ersetz das Komma durch einen Dezimalpunkt,
>und Deine Probleme sollten verschwinden...

>die Schreibweise für "Kommazahlen" in C ist Punkt statt Komma, also:

>Vielleicht hätte auch schon das Ersetzen des Kommas durch einen Punkt
>zum erwarteten Ergebnis geführt.

>Mit dem Komma handelst du dir wohl ein Problem ein. Schreibe stattdessen

>Syntaktisch ist das korrekt, das nennt man KOMMAOPERATOR; gerechnet
>wird aber anders:

Abderrahim, wenn das am Komma liegt gibt's Freibier für alle!

Was sagt denn der Compiler, wenn du einen Dezimalpunkt statt eines 
Kommas verwendest?

>>Wenn du mit C arbeitest, kannstu dich aufn Kopf stellen:
>Das verletzt!

Warum? Das ist wirklich Käse! Entweder dein Code oder dein Compiler.
Du sagst selbst, dass die Materie neu für dich ist - dann folge doch 
einfach mal dem Rat der Leute, die das schon was länger machen. Im 
schlimmsten Falle irren wir uns alle und haben was gelernt, im besten 
Falle funktioniert dein Code und du hast was gelernt.

Gruß
Kai

ps: stell dir den Beitrag weiter oben vor ;) - ihr seid ja schon einen 
Schritt weiter
#874172
Lesenswert?

Also:
1) In den "Kommazahlen" immer "." statt "," schreiben
2) in den Projekteinstellungen/Kompileroptionen schauen, wie man deinem 
Compiler beibringt, die nötigen Float-Funktionen mit einzubinden.

Alternativ: die oben vorgeschlagene Fixpunktarithmetik verwenden.

3) Bildformate lesen, und das nächste Mal die Screenshots als PNG 
anhängen.
Fertig.
Gast #874297
Lesenswert?

Autor: Matthias Lipinsky (lippy)
Datum: 21.05.2008 20:38
wollte sagen, dass durch das Ergebnis der Multiplikation 17692 * 407 = 
7'200'644  nicht in eine word-Variable passt und deswegen nur noch die 
16 unteren Bits (uint16) 57219  drinstehen werden.

Das ist einer der häufigsten Fehler beim Programmieren.

Du musst auf (long int) casten  oder  eine temporäre long int-Variable 
für das Ergebnis definieren.

    Lin_current_value_x = (long int)(17692*val_x/10000);
oder
    Lin_current_value_x = 17692L * val_x / 10000;

Besser, da 10000 für einen µC eine krumme Zahl (0x2710) ist:
unsigned int Lin_current_value_x;
    Lin_current_value_x = (1.7692*1024L * val_x + 555.2*1024L) / 1024;
oder
    Lin_current_value_x = (1.7692*32768L * val_x + 555.2*32768L) / 
32768;


Sobald der Compiler einmal ein L sieht, führt er alle Berechnungen 
des Ausdruckes  als long aus.

@Benedikt:
Xsoll= ((1.7692*1023)*Xist+(555,2*1023))/1023;
Ja, multiplizieren kann er schon beim Compilen, aber dividieren muss er 
zur Runtime.
Gast #875434
Lesenswert?

eins hab ich nicht geachtet, und  vielleicht ist das der Grund warum ich 
die Fehler bekam,
"val_x" ist eine word-Variable.
Kann sein dass der Compiler keine words mit floats multiplizieren kann?
#875482
Lesenswert?

Na schön. Dann verlierst du aber MASSIV an Genauigkeit beim Abspeichern 
in ein Ganzzahlformat. Dem kannst du abhelfen, indem du das Ergebnis 
aufbläst (heisst: Multiplizieren um mit so vielen Zehnerpotenzen wie 
möglich, ohne dass was überläuft) und dieses bei der weiteren Berechnung 
berücksichtigst. Wenns ne Spannung ist, kann man das Ergebnis z.B. in mV 
statt Volt angeben oder auf was beliebiges andres normieren.

Zum Rechnen mit Ints statt Floats gibts hier auch nen Wikieintrag.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren