Forum: Mikrocontroller und Digitale Elektronik Runden ohne float


von Klaus R. (hpw70)


Lesenswert?

Hallo,

gibt es eine Möglichkeit, Werte ohne float zu verwenden zu runden?

Ich lese meinen 10 Bit AD-Wandler ein multipliziere * 100 für die 2 
Nachkommastellen. Kann ich die irgendwie Runden, das ich bei 3.952 nicht 
3 stehen habe sondern 4 ?

von Peter II (Gast)


Lesenswert?

Klaus Rabke schrieb:
> Kann ich die irgendwie Runden, das ich bei 3.952 nicht
> 3 stehen habe sondern 4 ?

vorher einfach +0.5 rechnen.

von Klaus R. (hpw70)


Lesenswert?

Wie soll ich die 0.5 schreiben, ohne float?

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Rabke schrieb:
> Ich lese meinen 10 Bit AD-Wandler ein multipliziere * 100 für die 2
> Nachkommastellen.

ergibt das einen Sinn ? 10 Bit ADC ergibt werte von 0-1023
Multipliziert mit 100 ergibt das einen Bereich von 0-102300.
alles Ganzzahlen.

von Peter II (Gast)


Lesenswert?

Klaus Rabke schrieb:
> Wie soll ich die 0.5 schreiben, ohne float?

ich weiss doch nicht wo du die  3,952 hast.
> Kann ich die irgendwie Runden, das ich bei 3.952 nicht

könntest ja mal etwas code zeigen.

von Sebastian V. (sebi_s)


Lesenswert?

Klaus Rabke schrieb:
> Kann ich die irgendwie Runden, das ich bei 3.952 nicht
> 3 stehen habe sondern 4 ?

Für das Beispiel das hier rechnen: (3952 + 500)/1000

von Udo S. (urschmitt)


Lesenswert?

Marc D. schrieb:
> ergibt das einen Sinn ? 10 Bit ADC ergibt werte von 0-1023
> Multipliziert mit 100 ergibt das einen Bereich von 0-102300.

Eben, wie kommst du von diesen Ganzzahlen zu den

Klaus Rabke schrieb:
> 3.952

???

Allgemein: Ganzzahlwert, der durch Teilen Stellen verliert. Statt 
abschneiden runden geht indem du vorher die Hälfte des Teilers 
dazuaddierst.

Beispiel, du willst die beiden letzten Stellen weghaben:

(5051 + 50) / 100 = 5101 / 100 = 51
(5049 + 50) / 100 = 5099 / 100 = 50

Nachtrag: Sebi war schneller :-)

von Klaus R. (hpw70)


Lesenswert?

@Marc D

Ich multipliziere * 100, weil ich hinterher durch 204.8 und später noch 
durch  2.05 teilen muss, mit * 100 kann ich zuerst durch 20480 und 
später mit 205 teilen.

Der Teil sieht jetzt so aus, funktioniert aber nicht wie gewünscht:
1
Enr = Gz / 20480;
2
Hstl = (Gz % 20480)/205;
3
Runden = (Hstl * 2);
4
Runden = Runden + 1;
5
Hstl = Runden / 2;

von Sinus T. (micha_micha)


Lesenswert?

In diesem Unterforum:
"Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel vorstellen 
und diskutieren. Bitte hier keine Fragen posten!"

von Klaus R. (hpw70)


Lesenswert?

Sorry, ich bin neu und komm noch nicht so zurecht auf der Seite.

von Peter II (Gast)


Lesenswert?

Klaus Rabke schrieb:
> Runden = (Hstl * 2);
> Runden = Runden + 1;
> Hstl = Runden / 2;

das kann ja auch nicht gehen.
1
4 * 2 = 8
2
8 + 1 = 9
3
9 / 2 = 4


hier sollte man ansetzen
1
Hstl = (Gz % 20480)/205;

mache mal:
1
Hstl = ((Gz % 20480)+103)/205;

von Klaus R. (hpw70)


Lesenswert?

Entspricht:

> Runden = (Hstl * 2);
> Runden = Runden + 1;
> Hstl = Runden / 2;

nicht Runden + 0.5?!

Peter II schrieb:
> Klaus Rabke schrieb:
>> Kann ich die irgendwie Runden, das ich bei 3.952 nicht
>> 3 stehen habe sondern 4 ?
>
> vorher einfach +0.5 rechnen.

von Peter II (Gast)


Lesenswert?

Klaus Rabke schrieb:
> Entspricht:
>
>> Runden = (Hstl * 2);
>> Runden = Runden + 1;
>> Hstl = Runden / 2;
>
> nicht Runden + 0.5?!

nein:

[c]
4 * 2 = 8
8 + 1 = 9
9 / 2 = 4

//oder mit 5

5 * 2 = 10
10 + 1 = 11
11 / 2 = 5

[c]

von Pandur S. (jetztnicht)


Lesenswert?

Weshalb soll ueberhaubt geteilt werden ? Man kann doch auch mit 
Ganzzahlwerten vom ADC weiterrechnen.

von Klaus R. (hpw70)


Lesenswert?

Jetzt Nicht schrieb:
> Weshalb soll ueberhaubt geteilt werden ? Man kann doch auch mit
> Ganzzahlwerten vom ADC weiterrechnen.

Weil diese Wert anschliessend ausgegeben werden.

von WS (Gast)


Lesenswert?

Hallo,
ich würde wie folgt rechnen:

Wenn:
x = ADC * k

dann
x*100 = (ADC  k  200 + 1) / 2 ... gerundet

dann aus x*100 die Einer und Hundertstel rechnen.

Gruss

WS

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Rabke schrieb:

> Ich multipliziere * 100, weil ich hinterher durch 204.8 und später noch
> durch  2.05 teilen muss, mit * 100 kann ich zuerst durch 20480 und
> später mit 205 teilen.


Davon hast du nicht gesagt. Macht aber in dem Kontext immer noch kein 
Sinn.

1023 (dein max. ADC Wert) * 100 = 102300
102300 / 20480 = 4,99x
4,99x / 205 = 0.024
Runden wir dann ist das Ergebnis = 0.
Das gilt dann auch für alle kleineren ADC werte.
Du kannst also gleich mit 0 Weitermachen und dir dann auch gleich
den ADC ersparen.

Ansonsten einfach kein float verwenden und nur mit int16_t bzw. int32_t
Rechnen.
102300 / 20480 = 4 weil das einfach stumpf abgeschnitten wird.

von Klaus R. (hpw70)


Lesenswert?

Marc D. schrieb:
> 102300 / 20480 = 4 weil das einfach stumpf abgeschnitten wird.

Richtig, so soll es auch.

Marc D. schrieb:
> 4,99x / 205 = 0.024

es ist nicht 4.99 / 205, es ist (102300 % 20480) / 205

von WS (Gast)


Lesenswert?

Wenn Du ADC*100 rechnen kannst (i32) dann kannst Du auch ADC*1000 
rechnen.

(ADC*1000 + 1024) / 2048

Bsp.:

ADC=1013

(1013 * 1000 + 1024) / 2048 (= 495,1289) = 495

ADC=1012
(1012 * 1000 + 1024) / 2048 (= 494,1406) = 494

Oder?

WS

von Bitflüsterer (Gast)


Lesenswert?

Da kann man eine ganz klare Empfehlung aussprechen: Am großen Zeh 
spielen für Anfänger. Alles andere ist für den TO schlicht zu hoch.

Weder kann er lesen, noch was er liest verstehen oder danach handeln, 
noch verstehen was er will oder es korrekt ausdrücken.

Reine Zeitverschwendung.

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Rabke schrieb:
> Marc D. schrieb:
>> 4,99x / 205 = 0.024
>
> es ist nicht 4.99 / 205, es ist (102300 % 20480) / 205

Huch nun doch eine modulo Rechnung hast du auch nicht erwähnt.
Aber auch hier gilt das gleiche.

(102300 % 20480) / 205 = 99,41463414634146
oder mit Ganzzahltypen gerechnet 99.

Einfach float nicht benutzen und Glücklich sein.

von Klaus R. (hpw70)


Lesenswert?

Marc D. schrieb:
> Huch nun doch eine modulo Rechnung hast du auch nicht erwähnt.

Habe ich, 11:25:

Klaus Rabke schrieb:
> Enr = Gz / 20480;
> Hstl = (Gz % 20480)/205;
> Runden = (Hstl * 2);
> Runden = Runden + 1;
> Hstl = Runden / 2;

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Rabke schrieb:
> Marc D. schrieb:
>> Huch nun doch eine modulo Rechnung hast du auch nicht erwähnt.
>
> Habe ich, 11:25:

Stimmt, Mein Fehler. Und besser nun ?

Was passt dir daran nicht INT einfach wegzulassen wenn du kein float 
erwünscht ?

von Marc (gierig) Benutzerseite


Lesenswert?

Klaus Rabke schrieb:
> Marc D. schrieb:
>> Huch nun doch eine modulo Rechnung hast du auch nicht erwähnt.
>
> Habe ich, 11:25:

Stimmt, Mein Fehler. Und besser nun ?

Was passt dir daran nicht einfach nur Ganzzahlen zu verwenden und
dementsprechend mit den Rundungsfehler zu leben ?

von W.S. (Gast)


Lesenswert?

Klaus Rabke schrieb:
> gibt es eine Möglichkeit, Werte ohne float zu verwenden zu runden?

Nein.
Runden ist immer der Vorgang, wo Nachkommastellen beseitigt und aus 
dem Ergebnis was ganzzahliges gemacht wird. Mit gewöhnlichen 
Integerzahlen gibt es sowas aus Prinzip nicht.

Ähem...es sei denn, du arbeitest mt FPGA's, wo bestimmte Sorten von 
Festkommazahlen definiert sind.

Ansonsten scheint mir dein Denkansatz schlichtweg kraus. Wenn du das 
richtige Skalieren nicht beherrschst, dann nimm float und fertig isses.

W.S.

von WS (Gast)


Lesenswert?

Hallo W.S.,
man kann runden, wenn man Festkommazahlen benutzt. Also kann man mit 
Integerzahlen runden, wenn man weiß wie es geht.

Wenn ich also einen Interger*32 Wert habe, der das 1000-fache des 
Ergebnisses darstellt, kann ich runden. Sogar nach der zweiten Stelle.

Man braucht keinen Float, man braucht einen Algorithmus:

(ADC*1000 + 1024) / 2048

Gruß

WS

von WS (Gast)


Lesenswert?

vollständig:

GZ = (ADC*1000 + 1024) / 2048

Enr  = (GZ / 100)
Hstl = (GZ % 100)

Gruß

WS

von WS (Gast)


Lesenswert?

Mit i16:
Gz = (adc*31 + adc/4 + 32) / 64

WS

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.