Forum: Mikrocontroller und Digitale Elektronik 10bit int to 16bit int


von sven s. (Gast)


Lesenswert?

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

von sven s. (Gast)


Lesenswert?

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

von bwisser (Gast)


Lesenswert?

??????
uint16_t adc_wert = adc_register;
oder
uint16_t adc_wert = (uint16_t)adc_register;

von Stefan E. (sternst)


Lesenswert?

1
if (result & (1<<9))
2
    result |= 0xfc00;

von (prx) A. K. (prx)


Lesenswert?

Wert im ADC-Register linksbündig ausrichten und direkt als 16-Bit 
Integer weiterverarbeiten (+/-32K statt +/-512).

von Klaus W. (mfgkw)


Lesenswert?

Wieso +/-?
Der ADC-Wert ist doch erstmal unsigned.
=>  [0..65535] statt [0..1023]

von (prx) A. K. (prx)


Lesenswert?

Nicht, wenn man Differenzmessung durchführt. Hatte den Eindruck, dass es 
hier darum ging.

von Klaus W. (mfgkw)


Lesenswert?

hm, schwer zu sagen bei der ausführlichen Beschreibung :-)

von Maxx (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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).

von Simon B. (nomis)


Lesenswert?

Also, für unsigned Werte würde ich für die Spreizung ja vorschlagen:

int16 = (int10 << 6) | (int10 >> 4);

Viele Grüße,
        Simon

von Maxx (Gast)


Lesenswert?

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.

von Maxx (Gast)


Lesenswert?

"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.

von Maxx (Gast)


Lesenswert?

(sorry mein letzter beitrag bezog sich auf den gelöschten), da nicht 
registriert kann ich selbst nicht löschen)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.