473,386 Members | 1,775 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Shift Operation

Hi All,

Could you please explain whether C standard supports logical right
shift operation using some operator?

I know somewhere I read about >>operator. I thought, it is in C but i
think i'm wrong about it. No where google helps me determining this
lapse in my memory. MSVC 6 compiler gives me error.

Thanks && Regards,
Nishu

Oct 9 '06 #1
24 3143
Nishu said:
Hi All,

Could you please explain whether C standard supports logical right
shift operation using some operator?
C's right shift operator, >>, works like this:

A >B will yield a result that is equivalent to A shifted right through B
bit positions. If A is negative, the result is implementation-defined.

There is also a >>= operator, of course, so that you can do A >>= B instead
of A = A >B
I know somewhere I read about >>operator. I thought, it is in C
No, 'fraid not.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 9 '06 #2

Richard Heathfield wrote:
Nishu said:
Hi All,

Could you please explain whether C standard supports logical right
shift operation using some operator?

C's right shift operator, >>, works like this:

A >B will yield a result that is equivalent to A shifted right through B
bit positions. If A is negative, the result is implementation-defined.
If i take a signed integer, so right shifting a negative int should
give me another negative int (signed arithmetic) or a positive integer.
Is this C standard defines or implementation defines?

Actually i want to know whether
long A;
A = 0xFFFFFFFF;

A >>= 1;

A &= 0x80000000

if(A)
{
printf("operator is arithmetic right shift");
}
else
{
printf(" operator is logical right shift");
}
Thanks.
Nishu

Oct 9 '06 #3
"Nishu" <na**********@gmail.comwrote:
Could you please explain whether C standard supports logical right
shift operation using some operator?
No. Or rather, not reliably.

Right shifting on unsigned integers is, of course, neither logical nor
arithmetical (or both, if you wish); zeros get shifted in from the high
end, but there is no sign bit to copy or not to copy.

Right shifting on signed integers is different for positive and negative
signed integers.
If the signed integer has a positive or zero value, zero bits are
shifted in from the high end just as for unsigned types; it makes no
difference whether this is because it is a logical shift, or whether
it's an arithmetical shift with a zero sign bit being copied. A zero bit
is, after all, equal to any other zero bit.
If, however, the signed integer has a negative value, the resulting
value is implementation-defined. This means that your program is not
allowed to crash on this operation[1], but the Standard doesn't require
any particular result. All it requires is that your implementation
defines what the result will be. This could be a logical shift, an
arithmetical shift, or something entirely different (which might makes
sense on, e.g., one's-complement machines).

So in short, _your compiler_ might use a logical right shift if you use
the normal C >shifting operator, but that assumption is not portable:
there's no guarantee that this will work on the next platform you try it
on.
I know somewhere I read about >>operator. I thought, it is in C but i
think i'm wrong about it.
There is indeed no such thing.

Richard

[1] Unlike _left_-shifting a signed integer where the result would
overflow; that is undefined, and may therefore crash.
Oct 9 '06 #4
In article <11*********************@k70g2000cwa.googlegroups. com>,
Nishu <na**********@gmail.comwrote:
>If i take a signed integer, so right shifting a negative int should
give me another negative int (signed arithmetic) or a positive integer.
Is this C standard defines or implementation defines?
Implementation. Except that those aren't the only two choices
available to the implementation...
>Actually i want to know whether
>long A;
A = 0xFFFFFFFF;
>A >>= 1;
>A &= 0x80000000
>if(A)
{
printf("operator is arithmetic right shift");
}
else
{
printf(" operator is logical right shift");
}
You are presuming that A = 0xFFFFFFFF will store a negative number
in A. That is a bad assumption:

1) long might have more than 32 bits, in which case 0xFFFFFFFF
would just be a regular signed number. It is not uncommon for long
to be 64 bits with int being 32 bits, short 16 bits, char 8 bits.
But it is also not uncommon for int and long both to be the same size
of 32 bits; there are also a number of compilers for which
long is 32 bits, int is 16 bits...

2) 0xFFFFFFFF is not specifically indicated as a long constant via an 'L'
suffix; interpretation of it starts out by considering it as a
signed int. No negative sign is present in the number, so the
compiler will inspect to determine whether 0xFFFFFFFF fits within
the positive range of signed int on that system; if it does then
0xFFFFFFFF would be considered a positive signed int and there would
then be an implicit cast of that positive signed int into a long for
storage into A; as long is promised to be at least as wide as int,
that would either involve leaving the number unchanged or else
widening it if necessary; widening on most systems would involve
sticking the value in the low bits and zero-filling the upper bits,
but int and long need not have the same internal padding bit structures
so an actual representation change might take place.

If the compiler determines that 0xFFFFFFFF does not fit within
the positive range of signed int, then it would reconsider it as
potentialy being a positive signed long; if it does not fit within
a positive signed long, then it would convert it to unsigned long, which
it should fit into. So you would now have an unsigned long constant
token and you would have a simple long destination to store it into.
The C standard says that if you attempt to store an unsigned
value into a signed location, and the unsigned value fits within
the positive range of the signed type, then the positive value
will be stored -- but it also says that if the unsigned value does
*not* fit within the positive range of the signed type, that the
result of the conversion is up to the implementation. Thus,
long A = 0xFFFFFFFF is not necessarily going to produce a negative
result in A, even if the implementation happens to use 32 bit long.
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
Oct 9 '06 #5
Nishu said:
Richard Heathfield wrote:
<snip>
>If A is negative, the result is implementation-defined.

If i take a signed integer, so right shifting a negative int should
give me another negative int (signed arithmetic) or a positive integer.
Is this C standard defines or implementation defines?
If A is negative, the result is implementation-defined.
Actually i want to know whether
long A;
A = 0xFFFFFFFF;

A >>= 1;

A &= 0x80000000

if(A)
{
printf("operator is arithmetic right shift");
}
else
{
printf(" operator is logical right shift");
}
If A is negative, the result is implementation-defined.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 9 '06 #6

Walter Roberson wrote:
In article <11*********************@k70g2000cwa.googlegroups. com>,
Nishu <na**********@gmail.comwrote:
If i take a signed integer, so right shifting a negative int should
give me another negative int (signed arithmetic) or a positive integer.
Is this C standard defines or implementation defines?

Implementation. Except that those aren't the only two choices
available to the implementation...
< snip>
The C standard says that if you attempt to store an unsigned
value into a signed location, and the unsigned value fits within
the positive range of the signed type, then the positive value
will be stored -- but it also says that if the unsigned value does
*not* fit within the positive range of the signed type, that the
result of the conversion is up to the implementation. Thus,
long A = 0xFFFFFFFF is not necessarily going to produce a negative
result in A, even if the implementation happens to use 32 bit long.
Thanks. I got it. C is indeed very flexible and benevolent to
compilers. :)

-Nishu

Oct 9 '06 #7

Nishu wrote:

I know somewhere I read about >>operator. I thought, it is in C but i
think i'm wrong about it.
>>(unsigned right shift) exists in Java <http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.19>, but not in standard C.
Oct 9 '06 #8
Nishu posted:
I know somewhere I read about >>operator.

Maybe you could write one yourself? If you know that "unsigned int" and
"signed int" have no padding, then you could simply do:

int i = -57;

*(unsigned*)&i >>= 4;

Or maybe something like:

i < 0 ? (i = -i) >>= 4, i = -i : i >>= 4

--

Frederick Gotham
Oct 9 '06 #9
Frederick Gotham wrote:
Nishu posted:
>I know somewhere I read about >>operator.
Where >>is meant to be a logical shift right.
Maybe you could write one yourself? If you know that "unsigned int" and
"signed int" have no padding, then you could simply do:

int i = -57;

*(unsigned*)&i >>= 4;
Given your limitations I believe this would work.
Or maybe something like:

i < 0 ? (i = -i) >>= 4, i = -i : i >>= 4
This one will overflow with INT_MIN if INT_MIN == -INT_MAX - 1, i.e. on
most 2s complement machines.
--
Flash Gordon
Oct 9 '06 #10
Frederick Gotham wrote:
Nishu posted:
I know somewhere I read about >>operator.

Maybe you could write one yourself? If you know that "unsigned int" and
"signed int" have no padding, then you could simply do:

int i = -57;

*(unsigned*)&i >>= 4;
This is legal in C99 [not sure about C90]. But you may not get the
'desired' result for sm or 1c machines.

--
Peter

Oct 10 '06 #11

Frederick Gotham wrote:
Nishu posted:
I know somewhere I read about >>operator.


Maybe you could write one yourself? If you know that "unsigned int" and
"signed int" have no padding, then you could simply do:

int i = -57;

*(unsigned*)&i >>= 4;
Typecasting is certainly good option. Thanks.

(unsigned) i >>= 1; /* (Results in logical shift) */

What is the purpose of doing it like *(unsigned*)&i >>= 1; ?

-Nishu

Oct 10 '06 #12
Nishu wrote:
Frederick Gotham wrote:
>Nishu posted:
I know somewhere I read about >>operator.

Maybe you could write one yourself? If you know that "unsigned int" and
"signed int" have no padding, then you could simply do:

int i = -57;

*(unsigned*)&i >>= 4;

Typecasting is certainly good option. Thanks.

(unsigned) i >>= 1; /* (Results in logical shift) */
Results in a disgnostic message, I hope. Cast-expressions are not
lvalues.
What is the purpose of doing it like *(unsigned*)&i >>= 1; ?
To bypass (in a somewhat clunky way) the restriction than cast-expressions
are not lvalues. I /think/ that you still get undefined behaviour, but
it might only be implementation-defined. Or I might be wrong. We're
having a warm October; maybe Hell is leaking.

--
Chris "Essen -9 and counting" Dollin
"I'm still here and I'm holding the answers" - Karnataka, /Love and Affection/

Oct 10 '06 #13
In article <qD*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
*(unsigned*)&i >>= 4;
Why not use the more transparent

i = ((unsigned)i) >4;

Taking the address of a variable may well prevent the compiler from
putting it in a register, though a sufficiently clever compiler would
not be fooled.

-- Richard
Oct 10 '06 #14

Nishu wrote:
If i take a signed integer, so right shifting a negative int should
give me another negative int (signed arithmetic)
Why would you ever want to do an "arithmetic" right shift on a negative
number?

Even if the "sign" bit got shifted into the top bits, the result is
mostly mathematically useless. i.e. shift of -1 on a two's complement
machine gives you .....

Oct 10 '06 #15
In article <11**********************@m7g2000cwm.googlegroups. com>,
Ancient_Hacker <gr**@comcast.netwrote:
>Why would you ever want to do an "arithmetic" right shift on a negative
number?
To divide by 2?
>Even if the "sign" bit got shifted into the top bits, the result is
mostly mathematically useless. i.e. shift of -1 on a two's complement
machine gives you .....
-1, which is (-1)/2 rounded down (which is the behaviour I usually
want from integer division).

-- Richard

Oct 10 '06 #16
Nishu posted:
(unsigned) i >>= 1; /* (Results in logical shift) */

As Chris mentioned, you might want to set your compiler to Strict C Mode if
it compiles that for you. No case ever results in an L-value in C.

--

Frederick Gotham
Oct 10 '06 #17
Richard Tobin posted:

i = ((unsigned)i) >4;

If I'm not mistake, this will not retain the original bit-pattern on systems
other than 2's complement.

--

Frederick Gotham
Oct 10 '06 #18
Frederick Gotham posted:
No case ever results in an L-value in C.
Typo correction:
No CAST ever results in a...
--

Frederick Gotham
Oct 10 '06 #19
Frederick Gotham wrote:
Richard Tobin posted:
i = ((unsigned)i) >4;

If I'm not mistake, this will not retain the original bit-pattern on systems
other than 2's complement.
If you care about the bit pattern, you probably shouldn't be using
signed integers anyway.

Oct 10 '06 #20

Harald van Dijk wrote:
Frederick Gotham wrote:
Richard Tobin posted:
i = ((unsigned)i) >4;
If I'm not mistake, this will not retain the original bit-pattern on systems
other than 2's complement.

If you care about the bit pattern, you probably shouldn't be using
signed integers anyway.
Yes, since most of the processors consider 2's complement signed
integers implementation, my interest is in relation to that only. (i =
((unsigned)i) >4;) It will_NOT retain the intended bit pattern for
signed arithmetic. Since, as C is flexible for >operation on signed
integers, C compilers come up >as arithmetic right shift, maintaining
the sign of the number while shifting and in case you need padding of
0s in MSBs for specific applications, just type CAST it to unsigned !!
Thanks a lot.

-Nishu

Oct 11 '06 #21
Nishu wrote:
>
Harald van Dijk wrote:
Frederick Gotham wrote:
Richard Tobin posted:
i = ((unsigned)i) >4;
>
If I'm not mistake,
this will not retain the original bit-pattern on systems
other than 2's complement.
If you care about the bit pattern, you probably shouldn't be using
signed integers anyway.

Yes, since most of the processors consider 2's complement signed
integers implementation, my interest is in relation to that only. (i =
((unsigned)i) >4;) It will_NOT retain the intended bit pattern for
signed arithmetic. Since, as C is flexible for >operation on signed
integers,
C compilers come up >as arithmetic right shift, maintaining
the sign of the number while shifting and in case you need padding of
0s in MSBs for specific applications, just type CAST it to unsigned !!
Thanks a lot.
What is your reason for not wanting to use the division operator
to acheive an arithmetic result?

What's wrong with (i /= 16)
instead of (i = ((unsigned)i) >4)?

--
pete
Oct 11 '06 #22

pete wrote:
>
<snip>
What is your reason for not wanting to use the division operator
to acheive an arithmetic result?

What's wrong with (i /= 16)
instead of (i = ((unsigned)i) >4)?
Well, It has nothing to do with the end result, which is obviously the
same. It is more specific in relation to optimization.
"Intelligent" (Better) compilers optimize division by the powers of 2
(2, 4, 8, etc) to the simple (and faster) right shift operations using
barrel shifters on fixed point processors (say, DSPs and ARM) but some
poor compilers evoke division "function call" which is not the optimal
way of doing this kind of division. Hence, just to avoid this
possibilty, better to use shift operation and Since C language (middle
level language) support it, it is better to do it there itself. This
obviously can be extended to multiply operations too..like multiple by
7, which is nothing but (8 - 1) and so on..

-Nishu

Oct 11 '06 #23
Nishu posted:
Well, It has nothing to do with the end result, which is obviously the
same. It is more specific in relation to optimization.
"Intelligent" (Better) compilers optimize division by the powers of 2
(2, 4, 8, etc) to the simple (and faster) right shift operations using
barrel shifters on fixed point processors (say, DSPs and ARM) but some
poor compilers evoke division "function call" which is not the optimal
way of doing this kind of division. Hence, just to avoid this
possibilty, better to use shift operation and Since C language (middle
level language) support it, it is better to do it there itself. This
obviously can be extended to multiply operations too..like multiple by
7, which is nothing but (8 - 1) and so on..

A lot of people think you should just write:

x /= 2;

, and let the compiler optimise it.

However, these same people still use static data in functions to boost
efficiency, so there's no bonafide rule for where you yourself should
optimise, and where the compiler should optimise on your behalf.

--

Frederick Gotham
Oct 11 '06 #24
Nishu wrote:
pete wrote:
>>
<snip>
>What is your reason for not wanting to use the division operator
to acheive an arithmetic result?

What's wrong with (i /= 16)
instead of (i = ((unsigned)i) >4)?

Well, It has nothing to do with the end result, which is obviously
the same. It is more specific in relation to optimization.
"Intelligent" (Better) compilers optimize division by the powers of
2 (2, 4, 8, etc) to the simple (and faster) right shift operations
using barrel shifters on fixed point processors (say, DSPs and ARM)
but some poor compilers evoke division "function call" which is
not the optimal way of doing this kind of division. Hence, just to
avoid this possibilty, better to use shift operation and Since C
language (middle level language) support it, it is better to do it
there itself. This obviously can be extended to multiply operations
too..like multiple by 7, which is nothing but (8 - 1) and so on..
You should leave it to the compiler optimizer, which is aware of
the number system used and can find these optimizations much better
than you can. Write for clarity. Unless you are writing the
actual optimizer.

--
Some informative links:
<news:news.announce.newusers
<http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>
Oct 11 '06 #25

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

388
by: maniac | last post by:
Hey guys, I'm new here, just a simple question. I'm learning to Program in C, and I was recommended a book called, "Mastering C Pointers", just asking if any of you have read it, and if it's...
43
by: Mehta Shailendrakumar | last post by:
Hello, Can anyone suggest me operator to perform arithmetic shift in C? May it be for a perticular compiler. Thank you in advance. Regards, Shailendra
2
by: Matt Sawyer | last post by:
Hi, I'm attempting to do a drag and drop operation from one listbox to another. I have my listboxes setup with SelectionMode = MultiExtended so that I can use the shift key, cntrl key, etc. to...
4
by: Felix Kater | last post by:
Hi, when I use something like int Shift= 3; long Value= 1 << Shift; What is the data type of the const value '1' here? In other terms: What is the possible maximum of 'Shift' here?
11
by: Bob Altman | last post by:
Hi all, I want to write a generic class that does this: Public Class X (Of T) Public Sub Method(param As T) dim x as T = param >3 End Sub End Class
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.