Code Comments
Programming Forum and web based access to our favorite programming groups.
I seem to be having yet more wierd issue with bit shifting. It seems
the following code doesnt do anything under gcc (ie it returns -1 as
both results). Anyone know why? Is it another language definition or
CPU issue?
main()
{
printf("%d\n",(int)0xFFFFFFFF >> 1);
printf("%d\n",(int)-1 >> 1);
}
B2003
Post Follow-up to this messageBoltar <boltar2003@yahoo.co.uk> writes:
> I seem to be having yet more wierd issue with bit shifting. It seems
> the following code doesnt do anything under gcc (ie it returns -1 as
> both results). Anyone know why? Is it another language definition or
> CPU issue?
>
> main()
> {
> printf("%d\n",(int)0xFFFFFFFF >> 1);
> printf("%d\n",(int)-1 >> 1);
> }
>
> B2003
Try using unsigned values and report back ...
Post Follow-up to this messageBoltar <boltar2003@yahoo.co.uk> wrote:
> printf("%d\n",(int)0xFFFFFFFF >> 1);
> printf("%d\n",(int)-1 >> 1);
Right-shifting a negative value results in an implementation-defined
value. As a first guess, your implementation does an arithmetic right
shift where you expected a logical one. Both results are allowed.
Richard
Post Follow-up to this messageBoltar wrote:
>
> I seem to be having yet more wierd issue with bit shifting. It seems
> the following code doesnt do anything under gcc (ie it returns -1 as
> both results). Anyone know why? Is it another language definition or
> CPU issue?
>
> main()
> {
> printf("%d\n",(int)0xFFFFFFFF >> 1);
> printf("%d\n",(int)-1 >> 1);
> }
Shift-right of negative values is implementation-defined; you're likely
to get one of arithmetic right shift or logical right shift. (Some machines
have/had only one of these and would have to synthesise the other, which
would be Woefully Inefficient.)
It's wise to restrict ones bitwise operations to unsigned types, since
these can't have tricksy sign bits to cut you with their nasty sharp
edges.
--
"The whole apparatus had the look of having been put /Jack of Eagl
es/
together with the most frantic haste a fanatically
careful technician could muster."
Hewlett-Packard Limited registered
no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 Engl
and
Post Follow-up to this messageBoltar wrote:
> I seem to be having yet more wierd issue with bit shifting. It seems
> the following code doesnt do anything under gcc (ie it returns -1 as
> both results).
It does something, namely to retain the signedness of your negative
values. It didn't have to. It could have shifted in zeros instead of
replicating the sign bit.
> Anyone know why? Is it another language definition or
> CPU issue?
It is a mistake on your part. See the code below.
> main()
> {
> printf("%d\n",(int)0xFFFFFFFF >> 1);
> printf("%d\n",(int)-1 >> 1);
> }
#include <stdio.h> /* mha: needed for the variadic
function printf */
int /* mha: main returns an int, say so */ main(void)
{
printf("right shifting a negative value has no portably\n"
"defined meaning, so the output of the next two\n"
"printf statements is up for grabs:\n");
printf(" ((int)0xFFFFFFFF >> 1) = %d\n", (int) 0xFFFFFFFF >> 1);
printf(" ((int)-1 >> ) = %d\n\n", (int) -1 >> 1);
printf("Note the difference in the following:\n");
printf(" (0xFFFFFFFF >> 1) = %u\n", 0xFFFFFFFF >> 1);
printf(" (int)(0xFFFFFFFF >> 1) = %d\n", (int) (0xFFFFFFFF >> 1));
return 0; /* mha: even if you can get away
without it, it is poor programming
practice not to return a value from
a function returning a value */
}
right shifting a negative value has no portably
defined meaning, so the output of the next two
printf statements is up for grabs:
((int)0xFFFFFFFF >> 1) = -1
((int)-1 >> ) = -1
Note the difference in the following:
(0xFFFFFFFF >> 1) = 2147483647
(int)(0xFFFFFFFF >> 1) = 2147483647
> B2003
Post Follow-up to this messageOn Apr 1, 4:00 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote: > Boltar <boltar2...@yahoo.co.uk> wrote: > > Right-shifting a negative value results in an implementation-defined > value. As a first guess, your implementation does an arithmetic right > shift where you expected a logical one. Both results are allowed. I always assumed bit shifting was just a shift of the register bits left or right and whether the value was being treated as signed or unsigned was completely irrelevant. Obviously not. :o( B2003
Post Follow-up to this messageOn Apr 1, 4:19 pm, Martin Ambuhl <mamb...@earthlink.net> wrote: > values. It didn't have to. It could have shifted in zeros instead of > replicating the sign bit. Thats what I would have expected. Its a shift , not a mathematic operation, the sign should be irrelevant and the value should just be treated as 32 seperate bits to be moved as appropriate. Why would anyone design this operation to preserve the sign? I don't understand. B2003
Post Follow-up to this message"Boltar" <boltar2003@yahoo.co.uk> wrote in message news:f82d8fac-0354-400a-a9f6-e03b6b2251e0@d21g2000prf.googlegroups.com... > On Apr 1, 4:19 pm, Martin Ambuhl <mamb...@earthlink.net> wrote: > > Thats what I would have expected. Its a shift , not a mathematic > operation, the sign should be irrelevant and the value should just be > treated as 32 seperate bits to be moved as appropriate. Why would > anyone design this operation to preserve the sign? I don't understand. Right-shifting used to be an efficient way of dividing integer values by powers of two. The sign propagation is necessary to make it work with twos-complement negative numbers. A processor often has a choice of right-shift operation (signed/unsigned) and you might be able to choose the one by shifting an unsigned value instead. -- Bart
Post Follow-up to this messageOn Apr 1, 4:43 pm, "Bartc" <b...@freeuk.com> wrote: > Right-shifting used to be an efficient way of dividing integer values by > powers of two. But not any longer , any modern CPU has a div or mul type instruction. > > The sign propagation is necessary to make it work with twos-complement > negative numbers. So why don't the same rules apply to the &, | and ^ operators then? For example why doesn't (int)-1 ^ 0xFFFFFFFF still give -1 instead of zero? B2003
Post Follow-up to this messageBoltar <boltar2003@yahoo.co.uk> writes: > On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.com> wrote: > > But not any longer , any modern CPU has a div or mul type instruction. > > > So why don't the same rules apply to the &, | and ^ operators then? > For example why doesn't (int)-1 ^ 0xFFFFFFFF still give -1 instead of > zero? > > B2003 Because its a bitwise operator and not a word operator. There is no notion of "sign" with single bits being or'd, and'ed or xor'ed.
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.