Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Arithmetic shift operation in C

Reply
Thread Tools

Arithmetic shift operation in C

 
 
Dik T. Winter
Guest
Posts: n/a
 
      06-16-2005
In article <> (Richard Bos) writes:
> Jean-Claude Arbaut <jean-> wrote:
>
> > Le 15/06/2005 15:43, dans d8pb9h$4r$, «*Mehta
> > Shailendrakumar*» <> a écrit*:
> >
> > > Thanks for the reply.
> > > But in case of right shift of signed integer, I have observed that sign
> > > doesn't get propogated and shift is performed as logical shift.

> >
> > It should ! Are you sure you declare your variables as "signed" ?

>
> No, it needn't. Right shifting a signed, negative integer gives
> implementation-defined results.


In the draft standard it still is undefined behaviour.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
 
 
 
Dik T. Winter
Guest
Posts: n/a
 
      06-16-2005
In article <> some idiot babbled:
> In article <> (Richard Bos) writes:

....
> > No, it needn't. Right shifting a signed, negative integer gives
> > implementation-defined results.

>
> In the draft standard it still is undefined behaviour.


My reading abilities apparently deteriorate when it is getting late.
Implementation-defined it is indeed.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      06-16-2005
CBFalconer <> wrote:

> Mehta Shailendrakumar wrote:
> >
> > Can anyone suggest me operator to perform arithmetic shift in C?
> > May it be for a perticular compiler.

>
> There is a lot of misinformation in the replies you have received.
> Shift operations in C are only portable, and properly defined, on
> unsigned objects.


This is not true. They are only portable, and properly defined, on
non-negative values. C never shifts objects, it shifts values; and a
shift of a signed integer which only involves representable non-negative
values is defined.
That is, right-shifting a non-negative signed integer works identically
to right-shifting an unsigned integer, both in C99 and C89. In C99, a
left-shift on a non-negative signed integer is also identical to the
operation done on an unsigned integer, as long as the result is
representable in the signed type; C89 does seem to leave this case
undefined.

> If you want to multiply or divide signed integer quantities by
> powers of two, just do so. The operators are '*' and '/'.


This, however, is true. Premature optimisation is the root of all evil.

Richard
 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      06-16-2005
Jean-Claude Arbaut wrote:

> Le 15/06/2005 16:27, dans d8pds6$8rp$, « Chris
> Dollin » <> a écrit :
>
>> Jean-Claude Arbaut wrote:
>>
>>> Le 15/06/2005 15:43, dans d8pb9h$4r$, « Mehta
>>> Shailendrakumar » <> a écrit :
>>>
>>>> Hi,
>>>>
>>>> Thanks for the reply.
>>>> But in case of right shift of signed integer, I have observed that sign
>>>> doesn't get propogated and shift is performed as logical shift.
>>>
>>> It should !

>>
>> Really? Are you sure that C requires this?

>
> Obviously, I wanted to quote that
>
>
> """
> The result ofE1 >> E2is 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/ 2E2. If E1 has a signed type and a negative
> value, the
> resulting value is implementation-defined.
> """


You don't say where your quoting from. In any case, that
text says that right-shifting a negative signed value gets
you an implementation-defined result. Your remark (above)
responds to

>>>> But in case of right shift of signed integer, I have observed that sign
>>>> doesn't get propogated and shift is performed as logical shift.


with

>>> It should !


implying that this is the expected - C-defined- result.
Since the result is *implementation*-defined, it's not
required by C.

[The implementation *could* always return 0. Or 17.]

--
Chris "electric hedgehog" Dollin
It's called *extreme* programming, not *stupid* programming.
 
Reply With Quote
 
Jean-Claude Arbaut
Guest
Posts: n/a
 
      06-16-2005



Le 16/06/2005 09:55, dans d8rb9a$h8$, «*Chris Dollin*»
<> a écrit*:

> You don't say where your quoting from. In any case, that
> text says that right-shifting a negative signed value gets
> you an implementation-defined result. Your remark (above)
> responds to


Pfff. It was a correction to a previous post where I admit
"it should" was rubbish (yet please admit it's common practice,
since on many processors there is a simple instruction sequence
to do that).

Reference is:
"""
International Standard ISO/IEC 9899, Second edition 1999-12-01,
Programming Languages - C,
Section 6.5.7, p85
"""

Is it sufficiently standard to you ?

 
Reply With Quote
 
Jean-Claude Arbaut
Guest
Posts: n/a
 
      06-16-2005

> However dividing a negative value by a power of 2 will not in general give
> the same result as an arithmetic right shift. For example gcc compiled the
> code:
>
> int div4(int value)
> {
> return value/4;
> }
>
> into:
>
>
> _div4:
> movl 4(%esp), %eax
> testl %eax, %eax
> js L4
> sarl $2, %eax
> ret
> .p2align 4,,7
> L4:
> addl $3, %eax
> sarl $2, %eax
> ret
>
>
> I.e. it optimised the division into a shift operation but for negative
> values it had to add 3 first to get the rounding right.
>
> Lawrence


On modern x86, gcc can eliminate the jump and use a conditionnal move:

movl 4(%esp), %eax
leal 3(%eax), %edx
cmpl $-1, %eax
cmovle %edx, %eax
sarl $2, %eax
ret

But that has nothing to do with the OP, it's just an optimization trick.

 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      06-16-2005
On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:

> CBFalconer <> wrote:
>
>> Mehta Shailendrakumar wrote:
>> >
>> > Can anyone suggest me operator to perform arithmetic shift in C?
>> > May it be for a perticular compiler.

>>
>> There is a lot of misinformation in the replies you have received.
>> Shift operations in C are only portable, and properly defined, on
>> unsigned objects.

>
> This is not true. They are only portable, and properly defined, on
> non-negative values. C never shifts objects, it shifts values;


That's tricky, a shift works at the representation level, and in addition
the standard defines the effect on values in some circumstances.

> and a
> shift of a signed integer which only involves representable non-negative
> values is defined.
> That is, right-shifting a non-negative signed integer works identically
> to right-shifting an unsigned integer, both in C99 and C89. In C99, a
> left-shift on a non-negative signed integer is also identical to the
> operation done on an unsigned integer, as long as the result is
> representable in the signed type; C89 does seem to leave this case
> undefined.


It doesn't define what happens in terms of value but it stil describes
what happens at the representation level.

>> If you want to multiply or divide signed integer quantities by powers
>> of two, just do so. The operators are '*' and '/'.

>
> This, however, is true. Premature optimisation is the root of all evil.


However dividing a negative value by a power of 2 will not in general give
the same result as an arithmetic right shift. For example gcc compiled the
code:

int div4(int value)
{
return value/4;
}

into:


_div4:
movl 4(%esp), %eax
testl %eax, %eax
js L4
sarl $2, %eax
ret
.p2align 4,,7
L4:
addl $3, %eax
sarl $2, %eax
ret


I.e. it optimised the division into a shift operation but for negative
values it had to add 3 first to get the rounding right.

Lawrence
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      06-16-2005
Lawrence Kirby wrote:
>
> On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
>
> > CBFalconer <> wrote:
> >
> >> Mehta Shailendrakumar wrote:
> >> >
> >> > Can anyone suggest me operator to perform arithmetic shift in C?
> >> > May it be for a perticular compiler.
> >>
> >> There is a lot of misinformation in the replies you have received.
> >> Shift operations in C are only portable, and properly defined, on
> >> unsigned objects.

> >
> > This is not true. They are only portable, and properly defined, on
> > non-negative values. C never shifts objects, it shifts values;

>
> That's tricky, a shift works at the representation level,
> and in addition
> the standard defines the effect on values in some circumstances.


Arithmetic right shifting a -1 may or may not yield a negative zero.

--
pete
 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      06-16-2005
Jean-Claude Arbaut wrote:

> Le 16/06/2005 09:55, dans d8rb9a$h8$, « Chris Dollin
> » <> a écrit :
>
>> You don't say where your quoting from. In any case, that
>> text says that right-shifting a negative signed value gets
>> you an implementation-defined result. Your remark (above)
>> responds to

>
> Pfff. It was a correction to a previous post where I admit
> "it should" was rubbish (yet please admit it's common practice,
> since on many processors there is a simple instruction sequence
> to do that).


Jolly good.

[It may be common practice; that wasn't the question. In fact,
given that it *is* common practice, it's even more important
to stress that it's *not specified by the language*, since
"common" is not "universal".]

> Reference is:
> """
> International Standard ISO/IEC 9899, Second edition 1999-12-01,
> Programming Languages - C,
> Section 6.5.7, p85
> """
>
> Is it sufficiently standard to you ?


Oh, yes. It's just that you didn't say so in the original.

--
Chris "electric hedgehog" Dollin
It's called *extreme* programming, not *stupid* programming.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      06-16-2005


Lawrence Kirby wrote:
> On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
>
>
>>CBFalconer <> wrote:
>>
>>
>>>Mehta Shailendrakumar wrote:
>>>
>>>>Can anyone suggest me operator to perform arithmetic shift in C?
>>>>May it be for a perticular compiler.
>>>
>>>There is a lot of misinformation in the replies you have received.
>>>Shift operations in C are only portable, and properly defined, on
>>>unsigned objects.

>>
>>This is not true. They are only portable, and properly defined, on
>>non-negative values. C never shifts objects, it shifts values;

>
>
> That's tricky, a shift works at the representation level, and in addition
> the standard defines the effect on values in some circumstances.


Disagreeing with L.K. in this forum carries more than a
little chance of making oneself ridiculous, but "fools rush
in" ... Here I go; draw your own conclusions:

The Standard describes the shift operators in terms of
a binary representation, but I think R.B. is right: they
operate on values, not on "the" representations. Consider
an `int' representation with padding bits: Assuming a shift
whose result is well-defined, the padding bits do not
affect any value bits of that result.

Here's a hypothetical `int' with one sign bit, fifteen
value bits, and two padding bits:

P S V V V V V V V P V V V V V V V V
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0

(I intend this to mean that the value of the `int' is 256,
that the leftmost padding bit is set, and that the padding
bit in the middle is clear.) Right-shifting this by one
position gives

P S V V V V V V V P V V V V V V V V
x 0 0 0 0 0 0 0 0 x 1 0 0 0 0 0 0 0

(Meaning: the value is 128, and the two padding bits have
unknown settings.)

Observe that the leftmost padding bit does not shift
into the sign position, nor does the middle padding bit
shift into the 128's position, nor does the 256's bit shift
into the middle padding position and get "swallowed" there.
The shift has affected the value bits in a way that is not
influenced by either of the padding bits. That is, the shift
has operated on the value, not on the representation.

The value/representation question can also be argued
without introducing exotica like padding bits. How are "bit
positions" defined in the first place? Not by reference to a
physical ordering: they could be left-to-right, top-to-bottom,
scattered in some strange pattern that conserves silicon --
they could even have no individual physical existence at all
in a computer built of four-state components each representing
a pair of bits. Nor can they be ordered by their addresses,
since even on a bit-addressable machine C has no way to talk
about the address of anything smaller than a complete `char'.
No, "bit positions" (and the "left" and "right" directions)
can only be described in terms of the powers of two in the
value.

I think the Standard's use of "representation" in describing
the shift operators is just for convenience of exposition, and
does not refer to the "representation" as described in 6.2.6.
Note that in addition to describing the shift result in terms
of bit positions, the Standard also describes it in purely
arithmetic form, as multiplication or division by an integer
power of two -- this latter part only makes sense when applied
to the value, not the representation, of the shifted quantity.

--


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Java left shift and right shift operators. Sanny Java 38 04-29-2011 10:02 PM
Boolean operation and arithmetic operation Buzz Lightyear C++ 10 08-12-2009 01:27 PM
Left Shift / Right Shift Operators Santosh Nayak C Programming 16 11-30-2006 05:10 PM
Shift - byte[] buf shift Roberto Gallo Java 3 01-27-2004 04:26 PM
left shift then right shift an unsigned int Wenjie C++ 3 07-11-2003 08:22 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57