By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,604 Members | 1,444 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,604 IT Pros & Developers. It's quick & easy.

regarding << and >> operators

P: n/a
#include<stdio.h>
int main(void){
printf("%d %d\n",32<<1,32<<0);
printf("%d %d\n",32<<-1,32<<-0);
<----------------------------------see here
printf("%d %d\n",32>>1,32>>0);
printf("%d %d\n",32>>-1,32>>-0);
<----------------------------------and here

return 0;
}

$ make
gcc -Wall -g -o test test.c
test.c: In function `main':
test.c:4: warning: left shift count is negative
test.c:6: warning: right shift count is negative
$ ./test
64 32
0 32 (1)
16 32
0 32 (2)

Why 0 is printed in (1) and (2) ??

Nov 15 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
In article <11**********************@m7g2000cwm.googlegroups. com>,
onkar <on*******@gmail.comwrote:
printf("%d %d\n",32<<-1,32<<-0);
printf("%d %d\n",32>>-1,32>>-0);
>0 32 (1)
>0 32 (2)
>Why 0 is printed in (1) and (2) ??
You got lucky and it printed out something that you recognize
immediately as being odd. If you had been less lucky, it might have
printed something you were expecting, and you might have then tried
to use the operation in a real program only to discover much too late
that your code was incorrect.

To phrase the above in a blunter form: *any* answer would have been
right, because the result of left or right shifting by a negative
value is undefined in C (as is the result of shifting by more than
the number of bits in the promoted value.)

--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Nov 15 '06 #2

P: n/a

onkar wrote:
#include<stdio.h>
int main(void){
printf("%d %d\n",32<<1,32<<0);
printf("%d %d\n",32<<-1,32<<-0);
<----------------------------------see here
printf("%d %d\n",32>>1,32>>0);
printf("%d %d\n",32>>-1,32>>-0);
<----------------------------------and here

return 0;
}

$ make
gcc -Wall -g -o test test.c
test.c: In function `main':
test.c:4: warning: left shift count is negative
test.c:6: warning: right shift count is negative
$ ./test
64 32
0 32 (1)
16 32
0 32 (2)

Why 0 is printed in (1) and (2) ??
Shifting by a negative value is undefined in standard C and also
nonsensical.

Nov 15 '06 #3

P: n/a
santosh wrote:
Shifting by a negative value is undefined in standard C
Yes.
and also nonsensical.
No.

It has an obvious meaning, and one that has been implemented
in at least one machine and at least one programming language.

(So acting on vague memory I googled "vax negative shift" and got
to the interesting http://yarchive.net/comp/shift_instruction.html.
I still haven't managed to recover the langaueg I remember with
neg-shits-t'other-way ...)

--
Chris "hantwig efferko VOOM!" Dollin
Nit-picking is best done among friends.

Nov 15 '06 #4

P: n/a
In article <ej**********@murdoch.hpl.hp.com>,
Chris Dollin <ch**********@hp.comwrote:
>Shifting by a negative value is undefined in standard C
[...]
>and also nonsensical.
>No.

It has an obvious meaning, and one that has been implemented
in at least one machine and at least one programming language.
And since the definition of shifting in the standard is in terms of
multiplication or division by 2^N, it would be natural to extend it to
negative shifts.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Nov 15 '06 #5

P: n/a
Chris Dollin wrote:
santosh wrote:
Shifting by a negative value is undefined in standard C

Yes.
and also nonsensical.

No.

It has an obvious meaning, and one that has been implemented
in at least one machine and at least one programming language.

(So acting on vague memory I googled "vax negative shift" and got
to the interesting http://yarchive.net/comp/shift_instruction.html.
I still haven't managed to recover the langaueg I remember with
neg-shits-t'other-way ...)
Interesting link. Straight from the horse's mouth too. I'll be sure to
read it later. Thanks.

Nov 15 '06 #6

P: n/a
Chris Dollin wrote:
santosh wrote:
>Shifting by a negative value is undefined in standard C

Yes.
>and also nonsensical.

No.

It has an obvious meaning, and one that has been implemented
in at least one machine and at least one programming language.
[OT] At the machine level, by giving meaning to negative shift
counts, you can implement a complete set of shifts with only two
instructions: ArithShift and LogicalShift. Two more are needed to
implement rotations. Double the count if you also need to
implement "through carry". One actual shift instruction with a 3
bit detail field will do it all.
[/OT]

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Nov 15 '06 #7

P: n/a
Richard Tobin wrote:
>
In article <ej**********@murdoch.hpl.hp.com>,
Chris Dollin <ch**********@hp.comwrote:
Shifting by a negative value is undefined in standard C
[...]
and also nonsensical.
No.

It has an obvious meaning, and one that has been implemented
in at least one machine and at least one programming language.

And since the definition of shifting in the standard is in terms of
multiplication or division by 2^N, it would be natural to extend it to
negative shifts.
But, what happens when the hardware includes bit-shift operators,
and the hardware itself assumes an unsigned shift value? If C were
to say "negative shifts mean shift in the opposite direction", then
every non-constant shift would have to convert:

x << y

to the equivalent of:

( y < 0 ) ? (x >-y) : (x << y)

(Without the issue of side-effects, of course.)

Hardly an efficient operator, is it?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 15 '06 #8

P: n/a
In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
>And since the definition of shifting in the standard is in terms of
multiplication or division by 2^N, it would be natural to extend it to
negative shifts.
>But, what happens when the hardware includes bit-shift operators,
and the hardware itself assumes an unsigned shift value?
I was giving the matural extensibility of the definition as further
evidence against the nonsensicality of negative shifts, not as an
argument for having them in C. The efficiency argument is,
unfortunately, overwhelming.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Nov 15 '06 #9

P: n/a
In article <45***************@yahoo.com>
CBFalconer <cb********@maineline.netwrote:
>[OT] At the machine level, by giving meaning to negative shift
counts, you can implement a complete set of shifts with only two
instructions: ArithShift and LogicalShift. Two more are needed to
implement rotations. Double the count if you also need to
implement "through carry". One actual shift instruction with a 3
bit detail field will do it all.
[/OT]
There is a much better way to do the whole thing, using an
extra argument. Consider the following ASCII-art diagram of
an 8-bit "shifter" (larger variants are obvious, but harder to
draw :-) ):

val1 val2
ABCDEFGH ijklmnop
\\\ /////
\\\ /////
||||||||
FGHijklm
result

If val1==0, bits A-H are all-zeros, and this computes val2 >3,
with val2 unsigned ("logical" shift).

If val1==-1, bits A-H are all-ones, and this computes val2 >3,
with val2 signed and its sign bit set ("arithmetic" shift).

If val2==0, bits i-p are all-zeros, and this computes val1 << 5.

If val1==val2, bits F-H are the same as bits n-p, and this computes
(val1 rotateleft 5) or, equivalently, (val2 rotateright 3).

If neither val1 nor val2 is all-zeros or all-ones, and not equal to
each other, this extracts an 8-bit sub-field from two 8-bit values.

The diagram above is of a "funnel shifter", which has three inputs
and one output. The inputs are two values (of some bit-size), and
a bit-index in the range [0..N-1], where N is the number of bits
in the values. (The instruction-set designer must decide whether
the "count" above is 3 or 5; either is OK.)

Note that a single 64-bit funnel shifter can implement 8, 16, or
32-bit shifts and rotates; you just have to arrange for the bits
to be shifted-or-rotated to be in the uppermost and lowermost bits
of the two "value" inputs, then choose the shift count correctly.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '06 #10

P: n/a
In article <ej**********@pc-news.cogsci.ed.ac.ukri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
....
And since the definition of shifting in the standard is in terms of
multiplication or division by 2^N, it would be natural to extend it to
negative shifts.
Perhaps. But what when the shiftcount is a variable that can be
positive or negative? Should there be a run-time check to see
which instruction to use?
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 15 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.