10bit int to 16bit int

Gast #1756049
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.
Persönliche Seite #1756095
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).
Gast #1756140
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.
Gast #1756176
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.
Persönliche Seite #1756307
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren