PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] Multiplikation, Casten



IRQ
09.03.2007, 13:18
Hi,

habe mit C noch nicht so viel gemacht, daher hab ich eine wohl triviale Frage:

Mit folgendem Code-Schnipsel lese ich die Spannung an einem AD-Wandler des atmega8 aus und gebe sie auf einem Display aus. Korrekter weise müsste die Umrechnung von Registerwert nach anliegender Spannung ja nach der Formel U = REGISTER / 1024 * 5 V erfolgen, wobei 5V meine Referenzspannung ist. Ich skaliere das mit dem Faktor 1000, weil ich nicht weiß, wie ich double zu string konvertiere (für erste Tests reicht das ja aus).


double d = (1000*5)/(1024);

while(1) {
a = adconvert(1); // Führt Konversation aus und gibt Registerinhalt zurück
voltage = (int) (a*d); // Berechnet die Spannung
// Hier noch Int->String und auf Display ausgeben
}

Leider liefert das falsche Ergebnisse, z.B. 360 V statt 430 V (wohlgemerkt mit Faktor 100 skaliert, also 0.43V...).

Auf Grund von allgemeiner Ahnungslosigkeit habe ich aus dem 1000/1024 einfach ne 1 gemacht und gleich mit 5V multipliziert, also:


voltage = a*5;

Und siehe da, es funktioniert! Von der Genauigkeit reicht mir das aus, allerdings wüsste ich gerne warum das mit der Multiplikation von int und float nicht so funktioniert wie es soll :-s

Dankeschön!

ogni42
09.03.2007, 13:49
Weil Du erst mal nur Integer miteinander multiplizierst und danach erst einen Float daraus machst.

5000/1024 = 4 (rest: 0.8828125)

Fehlerwert= (4.8828125-4)/4.8828125 = 18,08% (Probier's mal mit 360V aus)

besser ist:


const float vref = 5.0;
float scale = vref/1024.0;
float voltage = 0.0;
char buffer[7];

while(true)
{
voltage = scale * (float)adconvert(1);
sprintf( buffer, "%5.4f", voltage );
functionToPutStuffToDisplay(buffer);
}

IRQ
09.03.2007, 14:38
Achso, also bei der Multiplikation von float * int wird der float erst auf int gecastet, habe ich das richtig verstanden?

Die 18% Fehler hauen nämlich exakt hin und wie in deinem Vorschlag funktioniert es auch. Dankeschön!!!

ogni42
09.03.2007, 15:25
Bitteschön :D

Es ist so, dass Du in Deinem Beispiel erst einmal nur Integer miteinander multiplizierst. Dann erst (!) wird das Ergebnis einem float (double) zugeweisen.

Bei der Multiplikation int*float wird erst der int nach float konvertiert und dann multipliziert.