Hallo,
ich bekomme über den ADC einen Wert von 0 - 1023 rein. Diesen möchte ich
als 9 Bit signed darstellen.
int16_t adc = (adc_read(0)>>1)-255;
Jedoch ist der Wert am Ende doch falsch. Mit >>1 wird aus meinen max.
1023 511. Davon subtrahiere ich 255. Somit ist bei einem Vollausschlag
aber positive Wert 256 und nicht 255.
Setze ich den Wert aber in der Formel auf 256, dann passt der im
positiven Bereich, doch wenn der adc Rückgabewert = 0 ist, wird adc -256
Herman Uh. schrieb:> Davon subtrahiere ich 255. Somit ist bei einem Vollausschlag> aber positive Wert 256 und nicht 255.
Was du gerade rausgefunden hast, das ist, dass es bei einer geraden
Anzahl an Werten kein exakt in der MItte liegendes mittleres Element
gibt.
mal mit kleineren Werten probieren.
ANgenommen dein ADC liefert ausschliesslich die Werte 0, 1, 2, 3, wobei
3 den größtmöglichen Wert repräsentiert.
Welcher Wert soll nach der Transformation die 0 spielen?
1
0 1 2 3
2
| | | |
3
v v v v
4
-1 0 1 2
1
0 1 2 3
2
| | | |
3
v v v v
4
-2 -1 0 1
eine gewisse Asymetrie ist systemimanent und mit einer simplen
Transformation kannst du nichts dagegen tun, wenn du eine 0 erhalten
willst.
Herman Uh. schrieb:> Setze ich den Wert aber in der Formel auf 256, dann passt der im> positiven Bereich, doch wenn der adc Rückgabewert = 0 ist, wird adc -256
das ist doch aber gut, was stört dich daran?
Herman Uh. schrieb:> ich bekomme über den ADC einen Wert von 0 - 1023 rein. Diesen möchte ich> als 9 Bit signed darstellen.
9<10.
D.h.: du wirst Information abwerfen müssen, um dein Ziel zu erreichen,
nämlich genau ein Bit.
Also einfach eins nach rechts schieben (ergibt einen Bereich zwischen 0
und 511) und dann 256 abziehen, was einen Bereich zwischen -256 und 255
ergibt.
0 -> -256
512 -> 0
1023 -> 255
Trivialste Scheiße. Kein Assemblerprogrammierer würde darüber auch nur
eine Sekunde lang ernsthaft nachdenken müssen.
Fazit: C verblödet ganz offensichtlich seine Benutzer!
c-hater schrieb:> Fazit: C verblödet ganz offensichtlich seine Benutzer!
[ ] Ich hab verstanden, was das 'Problem' des Fragestellers ist
[ ] Ich habs nicht verstanden.
> Kein Assemblerprogrammierer würde darüber auch nur eine Sekunde lang ernsthaft
nachdenken müssen.
Auch ein Assemblerprogrammierer wird sich beim ersten mal darüber
Gedanken machen, wo diese Asymetrie in den positiven und negtaiven
Zahlenbereichen eigentlich herkommt.
Karl Heinz schrieb:> Auch ein Assemblerprogrammierer wird sich beim ersten mal darüber> Gedanken machen,
Korrekt, das sollte unabhaengig von der Programmiersprache sein.
Genau das hatte der TO aber nicht (oder zumindest nur oberflaechlich)
gemacht. Statt dessen werden heutzutage eben Postings in Foren erstellt.
wendelsberg
Karl Heinz schrieb:> [x] Ich hab verstanden, was das 'Problem' des Fragestellers ist> [ ] Ich habs nicht verstanden.
Das Problem ist, daß er nicht "ganz unten" angefangen hat.
> Auch ein Assemblerprogrammierer wird sich beim ersten mal darüber> Gedanken machen, wo diese Asymetrie in den positiven und negtaiven> Zahlenbereichen eigentlich herkommt.
Öhem. Was meinst du mit "das erste Mal"? Natürlich muß man auch als
Asm-Programmierer irgendwann die Zahlenrepräsentationen (z.B. im
Zweierkomplement) erstmal lernen und verstehen, das ist doch sowas von
klar, dass man das garnicht diskutieren muss.
Der Unterschied ist halt nur: Als Asm-Programmierer bist du sehr früh
hart dazu gezwungen, das zu lernen und aus dem ff zu beherrschen. Und
das ist sowas von GUT und hilfreich...
Selbst noch bei der Programmierung in echten Hochsprachen der 4.
Generation ist das der Fall (obwohl das dort nach der reinen Lehre
eigentlich garkeine Rolle mehr spielen sollte... ;o) und bei der
Programmierung in diesem gräßlichen Makroassembler-Dialekt namens C
natürlich erst recht...
Bei der Zahlen-darstellung im 2er-Komplement ist es allgemein üblich,
daß der Bereich im Negativen einen Wert mehr enthält. z.B. 16-Bit int:
-32768 .. 0 .. 32767. Bei dieser Darstellung ist das oberste Bit das
Vorzeichen-Bit, ist es gesetzt, ist die Zahl negativ. Bei der 0 ist es
nicht gesetzt, die 0 wird also den positiven Zahlen zugeordnet. Da es
immer genau so viele negative wie positive Zahlen gibt, ergibt sich die
oben genannte Verteilung. Mit der Variante -256 .. 0 .. 255 bist Du bei
der gebrauchlicheren Variante, was die weitere Verarbeitung der Werte
eventueller unproblematischer macht, Du könntest z.B. mit 128
multiplizieren, und der Wert füllt einen 16-Bit int aus, ohne für
Überläufe zu sorgen. 256 * 128 geht da schon nicht mehr, aber -256 * 128
geht gerade noch.
Mit freundlichem Gruß - Martin
c-hater schrieb:> Karl Heinz schrieb:>>> [x] Ich hab verstanden, was das 'Problem' des Fragestellers ist>> [ ] Ich habs nicht verstanden.
Falsch angekreuzelt.
> Öhem. Was meinst du mit "das erste Mal"? Natürlich muß man auch als> Asm-Programmierer irgendwann die Zahlenrepräsentationen (z.B. im> Zweierkomplement) erstmal lernen und verstehen, das ist doch sowas von> klar, dass man das garnicht diskutieren muss.
Das ist kein Problem der Programmiersprache und die Frage des TO hat
auch nichts mit 2-er Komplement zu tun.
Das ist ein ganz normales Matheproblem.
Bei einer geraden Anzahl an möglichen Werten in einer streng monoton
steigenden Menge mit aufeinander folgenden Zahlen, ist der Median nicht
Teil der Wertemenge bzw. ist es nicht möglich die Menge so in 2
Teilmengen und ein einzelnes Element aufzuteilen, dass die Teilmengen
gleiche Mächtigkeit haben.
Setzen, 6.
Schön langsam wirds lächerlich mit deinem C-Bashing. Was kommt als
nächstes? Ist C auch am Ukraine Konflikt Schuld? Am internationalen
Terrorismus? Wäre Merkel beliebter, wenn sie Assembler programmiert und
wann gibts das erste Oktoberfest-Fahrgeschäft, in dem man nur Zutritt
hat, wenn man die Flags im Statusregister von mindestens 5 CPUs
auswendig weiß?