I found this text which explains the rationale:
The Committee has affirmed the freedom in implementation granted by the Base Document in not requiring the signed right shift operation to sign extend, since such a requirement might slow down fast code and since the usefulness of sign extended shifts is marginal.
You can shift right a signed int like this:
Replicate sign bit: i = i / 2; (Doesn''t work for -1)
Don''t replicate sign bit: i = (unsigned)i >> 1;
signed integers and bit shifting
The moral of the story: Only do bitshifting to deal with bitfields, and then only with unsigned integers. Never use bitshifting in place of multiplication/division by a constant; you can trust the compiler to do it for you if it would actually be faster.
How appropriate. You fight like a cow.
[edited by - sneftel on June 17, 2003 1:41:22 PM]
How appropriate. You fight like a cow.
[edited by - sneftel on June 17, 2003 1:41:22 PM]
quote:Original post by Jan Wassenberg
CGameProgrammer: no difference between sal and shl. It''s not a bug, it''s the right thing to do (although the standard doesn''t guarantee that every compiler and CPU can manage).
Russell: umm.. the arithmetic (signed) shift right instruction?
Oh. Experimentation just proved you''re right. It seems kind of odd to me though -- shouldn''t sal preserve the sign bit? Sure, regardless of what it does the answer is still not "correct" since you''ve run out of space, but still.
~CGameProgrammer( );
S1CA was right on the money.
The C++ standard says for a right shift E1 >> E2 if E1 has a signed type and a negative value, the resulting value is implementation-defined.
For a left shift E1 << E2 it says that the value is E1 left-shifted E2 bits with vacant bits zero-filled. It also adds that for an unsigned type the value is equivalent E1 times 2 to the power of E2 but doesn''t mention signed types explicitly.
From this I would infer that left shifting a signed type may give a positive or negative result depending on the actual bit moved into the sign position.
Phil
--
Philip Dunstan
phil@philipdunstan.com
http://www.philipdunstan.com/
The C++ standard says for a right shift E1 >> E2 if E1 has a signed type and a negative value, the resulting value is implementation-defined.
For a left shift E1 << E2 it says that the value is E1 left-shifted E2 bits with vacant bits zero-filled. It also adds that for an unsigned type the value is equivalent E1 times 2 to the power of E2 but doesn''t mention signed types explicitly.
From this I would infer that left shifting a signed type may give a positive or negative result depending on the actual bit moved into the sign position.
Phil
--
Philip Dunstan
phil@philipdunstan.com
http://www.philipdunstan.com/
quote:Original post by CGameProgrammer
I just checked with a signed integer with Visual C++ 6.0. When shifting left, it used shl (the unsigned shift) but when shifting right it used sar (the signed shift). This is weird and a bug. You have to use sar/sal for signed and shl/shr for unsigned.
This isn''t a bug. There is no difference between sal and sar. They are the same opcode (basically: there is no sal instruction, it is simply an alias for shl).
quote:Original post by Jan Wassenberg
Indeed, it is defined. Trap representations can''t and won''t be generated from arithmetic on valid unsigned values.
I didn''t know for sure whether or not bit shifts were considered arithmetic. I guessed that they wouldn''t be (they manipulate the underlying representation rather than what it represents), but that was only a guess.
couldn''t you just overloaded the << operator so it does this?
of course i don''t remember offhand how to correctly do the overload of a function, but you get the idea.
signed int function (signed int number, unsigned int shift_num){(unsigned)number; number << shift_num; number = (signed)number * -1; return number;}
of course i don''t remember offhand how to correctly do the overload of a function, but you get the idea.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement