Hallo C-Profis,
ich habe ein Zahl die als Gleitkommazahl oder als String vorliegt, z.B.:
1.23456 bzw "1.23456".
Ich möchte nun das Komma(Dezimaltrenner, evtl .(Punkt)) beliebig
verschieben, also z.B.:
123.45 bzw "123.45".
Eine dunkle Ahnung sagt mir, dass ich mit Funktionen aus der math.h
arbeiten muss.
Die Zahl soll über RS232 auf ein Display ausgegeben werden.
Compiler: Codevision
MCU: ATmega64
C-Kenntnisse: 3-
Habt ihr vielleicht einen Lösungsansatz?
Vielen Dank für eure Mühe! - Ich koche auch für euch!
Johann Laver
Ja ja, ihr habt natürlich Recht. So war meine erste Lösung auch.
Aber: Die Werte stammen aus einen AD-Wandler, der z.B. den Wert 1,23456
Volt liefert. Auf Grund eines Widerstands-Vorteilers sind es in
Wirklichkeit 1234,56 Volt. Um diese Zahl zuerhalten, müsste ich mit 1000
multiplizieren. Und das möchte ich nicht, weil es zu Rundungsfehler in
der letzten Nachkommastelle kommen kann.
Ideal wäre es, wenn ich den Wert des AD-Wandlers so jungfreulich
erhalten könnte, wie er ist.
Gruß Johann
Wenn du die Zashl über UART / RS232 ausgibst, musst du sie vorher in
einen "n Stellen" großen String umwandeln. n entspricht der Anzahl der
Ziffern plus dem Komma.
Bei dieser Umwandlung kannst du das Komma an jeder beliebige Stelle
einbauen.
Gleitkommzahlen solltest du auf µC die keine FPU haben, vermeiden wo es
nur geht.
Besser du skalierst die Werte mit Faktoren aus der 2 Potenzen damit du
mit Ganzzahlwerten Rechnen kannst.
Also Faktor 2, 4 ,8 , 16 ,..........
Ich möchte den ADC sehen der den Wert 123.4 Volt liefert.
Der ADC liefert eine Ganzzahl ( Integer ) mit 8 oder 10 Bit zurück also
0 - 255 oder 0 - 1023.
Erst wenn du diesen Intergerwert mit der Auflösung multipliziertst
bekommst du die Spannung.
Also behalte den Integerwert und du verlierst keine Nachkommastellen.
Wenn du den Mega64 ADC nimmst (0 bis 1024), dein
Zwischenergebnis mit 1000 multiplizierst und dich beschwerst,
dass die 2. Nachkommastelle abweicht, dann hast du sowieso
etwas nicht verstanden:
Es ist sinnlos ein Ergebnis mit mehr Stellen anzugeben
als du überhaupt messen kannst. Das sind dann die Leute
die ein Aquariumthermometer auf 1/1000 Grad ablesen und sich
auch noch an den 3 Nachkommstellen erfreuen.
Gemach, gemach Leute,
ich habe geschrieben, dass der Wert aus einen AD-Wandler kommt, ich habe
nicht geschrieben, dass der Wert aus dem internen AD des mega 64 kommt.
Konkret: Mein AD ist ein 24-Bit-Modul, das, im Vergleich zu einem
7-1/2-stelligen Keithley-DMM die letzte Stelle in meiner Anzeige genau
liefert.
Insofern sind die Vorraussetzungen für eine genaue Messung gegeben.
Sagen wir mal du hast 0-5V Eingangsspannung. Das gäbe dann ein LSB von
ca 300 nV. Wenn du an den Eingang hauchst, zappeln die lezten paar LSB
mit Sicherheit. Ich finde das ist sowieso ein Marketinggag. Das Rauschen
wird schon ein x Faches höher sein. Ich schätze mal um den Faktor
tausend :)
Vielleicht wird es besser durch Mittelwert Bildung.
@ Johann Laver
>Aber: Die Werte stammen aus einen AD-Wandler, der z.B. den Wert 1,23456>Volt liefert. Auf Grund eines Widerstands-Vorteilers sind es in>Wirklichkeit 1234,56 Volt. Um diese Zahl zuerhalten, müsste ich mit 1000>multiplizieren. Und das möchte ich nicht, weil es zu Rundungsfehler in>der letzten Nachkommastelle kommen kann.
Eine Multiplikation mit 1000 bring nun wahrlich keine Rundungsfehler.
Auch n icht im Binärsystem.
MFg
Falk
Und wenn du deinen Messwert als String vorliegen hast, dann ist es umso
einfacher und garantiert rundungsfehlerfrei. Einfach das Komma (Punkt)
in ner Schleife suchen, die nachfolgenden ZEichen um eine Stelle
umkopieren, neunes Komma setzen. Ähhhh Voala.
MFG
Falk
Mach' ich hier den Eindruck, als sei ich nur doof?
Für die C-Programmierung mag das stimmen, deshalb mein Posting.
Für die Analog- und HF-Technik/Layout stimmt das NICHT!