Hallo, anbei mein code schnippsel wie ich das gelöst hab. jetzt wollt ich mal fragen ob das nicht ein bischen eleganter geht? if(result>= (1<<9)) { result-=(1<<9); result=(1<<9)-result; result=(1<<15)-result; result+=(1<<15); } gruß sven
achso.. ja falls jemand wissel will wofür das ganze und nicht gleich in seine kristallkugel gucken möchte ;-) http://www.atmel.com/atmel/acrobat/doc2466.pdf seite 216 gruß sven
?????? uint16_t adc_wert = adc_register; oder uint16_t adc_wert = (uint16_t)adc_register;
Wert im ADC-Register linksbündig ausrichten und direkt als 16-Bit Integer weiterverarbeiten (+/-32K statt +/-512).
Wieso +/-? Der ADC-Wert ist doch erstmal unsigned. => [0..65535] statt [0..1023]
Nicht, wenn man Differenzmessung durchführt. Hatte den Eindruck, dass es hier darum ging.
int16 = (int10 << 6) >> 6 ; Wenn du einen Barrelshifter zur Verfügung hast (i.e. ARM) sonst der Test+Or von Stefan (i.e. AVR) Vorteil des Shiftings: muss nicht angefasst werden wenn aus int10 ein uint10 wird. Und stellt in jedem Fall sicher, dass wirklich nur die unteren 10 Bits auch beachtet werden.
Maxx schrieb: > int16 = (int10 << 6) >> 6 ; Wenn du einen Barrelshifter zur Verfügung > hast (i.e. ARM) sonst der Test+Or von Stefan (i.e. AVR) > > Vorteil des Shiftings: muss nicht angefasst werden wenn aus int10 ein > uint10 wird. Und stellt in jedem Fall sicher, dass wirklich nur die > unteren 10 Bits auch beachtet werden. Ist aber nicht sonderlich portabel, weil >> für negative Werte implementation defined ist. Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10 gesetzt sein sollte (signed overflow).
Also, für unsigned Werte würde ich für die Spreizung ja vorschlagen: int16 = (int10 << 6) | (int10 >> 4); Viele Grüße, Simon
Johann L. schrieb: > Ist aber nicht sonderlich portabel, weil >> für negative Werte > implementation defined ist. Korrekt. Jedoch auf den Systemen, die einen Barrelshifter besitzen wohl anzunehmen. Jedenfalls ist mir noch kein ARM/x86 Compiler die mir dazu einfallen untergekommen der kein arithmetic shift right durchführt für signed. > Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10 > gesetzt sein sollte (signed overflow). Nicht Korrekt: (Auszug aus dem Ansi-C std) " The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity, 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise. (The constants ULONG_MAX and UINT_MAX are defined in the header <limits.h> .) The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 divided by the quantity, 2 raised to the power E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined." Die "Herausgeschifteten" Bits gehen also einfach nur verloren. Intern nutzt gcc-arm z.B. dieses Shifting um signed ordinal conversionen durchzuführen.
"E1 >> E2 is E1 right-shifted E2" Alles andere als arithmetic oder zero-filled verletzt diese Bedingung. (Da steht ja nicht "E1 << E2 is (E1 + some remains) right shifted E2" Insbesondere würde der Fall, dass die herausgeshifteten Bits nicht "vergessen" werden für ein C Programm bedeuten, dass
1 | int16 = (int10 << 6) ; |
2 | someotherval = aOne + aTwo ; |
3 | int16 = (int 16 >> 6) ; |
1 | int16 = (int10 << 6) ; |
2 | int16 = (int 16 >> 6) ; |
3 | someotherval16 = aOne + aTwo ; |
sich unterschiedlich verhalten. (Also der Übertrag mit geschiftet wird) PS: ein signed shift left ist immer identisch mit einem unsigned shift left. (Das if in der clause bezieht sich auf die multiplikation, die für signed/unsigned anders ausfallen würde), daher ist die Beschränkung des Linksschiebens formal irrelevant.
(sorry mein letzter beitrag bezog sich auf den gelöschten), da nicht registriert kann ich selbst nicht löschen)
Maxx schrieb: > Johann L. schrieb: >> Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10 >> gesetzt sein sollte (signed overflow). > Nicht Korrekt: (Auszug aus dem Ansi-C std) > " The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated > bits are filled with zeros. If E1 has an unsigned type, the value of > the result is E1 multiplied by the quantity, 2 raised to the power E2, > reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 > otherwise. (The constants ULONG_MAX and UINT_MAX are defined in the > header <limits.h> .) Hmmm. Zu signed macht das ja keine Aussage... ISO/IEC 9899 liest sich so:
1 | The result of E1 << E2 is E1 left-shifted E2 bit positions; |
2 | vacated bits are filled with zeros. If E1 has an unsigned type, |
3 | the value of the result is E1 * 2**E2, reduced modulo one more |
4 | than the maximum value representable in the result type. |
5 | If E1 has a signed type and nonnegative value, and E1 * 2**E2 is |
6 | representable in the result type, then that is the resulting value; |
7 | otherwise, the behavior is undefined. |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.