468,765 Members | 878 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

Arithmetic shift operation in C

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
Nov 14 '05 #1
43 25781

Le 15/06/2005 15:22, dans d8**********@ns2.fe.internet.bosch.com, «*Mehta
Shailendrakumar*» <sh*******************@de.bosch.com> a écrit*:
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

Ops are << and >>.
* n << k = n * 2^k
* n >> k = n / 2^k
But be careful with signed/unsigned differences,
As in the signed case, a high oerder bit is propagated
(to keep sign correct).
Just write a "toy program" to make some tests.

Nov 14 '05 #2
Mehta Shailendrakumar wrote:
Hello,
Can anyone suggest me operator to perform arithmetic shift in C?
May it be for a perticular compiler.

On many machines, >> operating on a signed int type would be called an
arithmetic right shift.
Nov 14 '05 #3
Mehta Shailendrakumar wrote:

Hello,
Can anyone suggest me operator to perform arithmetic shift in C?
May it be for a perticular compiler.


An arithmetic shift is what you get
when you mutliply or divide an integer by 2.

Shifting negative values is implementation defined.
Two variations that I'm aware of are
"logical shift" and "arithmetic shift".
For unsigned types, logical and arithmetic shifts are the same.

--
pete
Nov 14 '05 #4
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.
Does C standard states that ">>" operator is only for logical shift and not
for arithmetic shift?

Thank you.

Regards,
Shailendra

"Jean-Claude Arbaut" <je****************@laposte.net> wrote in message
news:BED5FA80.4436%je****************@laposte.net. ..

Le 15/06/2005 15:22, dans d8**********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> a écrit :
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

Nov 14 '05 #5

Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, «*Mehta
Shailendrakumar*» <sh*******************@de.bosch.com> 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 ! Are you sure you declare your variables as "signed" ?
Could you post your piece of code ?
Does C standard states that ">>" operator is only for logical shift and not
for arithmetic shift?

Thank you.

Regards,
Shailendra


Nov 14 '05 #6
Mehta Shailendrakumar wrote:

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.
Does C standard states that ">>"
operator is only for logical shift and not
for arithmetic shift?


No, either type of shift may be done by the >> operator.

If you want an arithmetic shift, then use an arithmetic operator.

integer /= 2

--
pete
Nov 14 '05 #7
Hi,

I checked again on signed integer.
It works properly.
Thank you.

Regards,
Shailendra
"Jean-Claude Arbaut" <je****************@laposte.net> wrote in message
news:BED5FE7F.447A%je****************@laposte.net. ..

Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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 ! Are you sure you declare your variables as "signed" ?
Could you post your piece of code ?
Does C standard states that ">>" operator is only for logical shift and not for arithmetic shift?

Thank you.

Regards,
Shailendra

Nov 14 '05 #8
Jean-Claude Arbaut wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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?

--
Chris "because, you know, it doesn't" Dollin
It's called *extreme* programming, not *stupid* programming.
Nov 14 '05 #9
On Wed, 15 Jun 2005 13:58:59 GMT,
pete <pf*****@mindspring.com> wrote:


If you want an arithmetic shift, then use an arithmetic operator.

integer /= 2


Carefull with negative integers.

#include <stdlib.h>
#include <stdio.h>

int main ()
{
printf("%x\n", -1235);
printf("%x\n", -1235 / 2);
printf("%x\n", -1235 >> 1);
return 0;
}
Villy
Nov 14 '05 #10
Jean-Claude Arbaut <je****************@laposte.net> wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, «*Mehta
Shailendrakumar*» <sh*******************@de.bosch.com> 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.

Richard
Nov 14 '05 #11

Le 15/06/2005 16:27, dans d8**********@malatesta.hpl.hp.com, «*Chris
Dollin*» <ke**@hpl.hp.com> a écrit*:
Jean-Claude Arbaut wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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?


Ok, mea culpa:

"""
The integer promotions are performed on each of the operands. The type of
the result is
that of the promoted left operand. If the value of the right operand is
negative or is
greater than or equal to the width of the promoted left operand, the
behavior is undefined.
"""

But unless you use a brain-damaged compiler, this is the usual behaviour,
though not "Standard". Now I wait for quibblings and their crazy counter
examples.

Nov 14 '05 #12

Le 15/06/2005 16:27, dans d8**********@malatesta.hpl.hp.com, «*Chris
Dollin*» <ke**@hpl.hp.com> a écrit*:
Jean-Claude Arbaut wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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.
"""

Nov 14 '05 #13


Jean-Claude Arbaut wrote:


Le 15/06/2005 16:27, dans d8**********@malatesta.hpl.hp.com, « Chris
Dollin » <ke**@hpl.hp.com> a écrit :

Jean-Claude Arbaut wrote:

Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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?



Ok, mea culpa:


Only your latest -- and, I fear, probably not your last.
"""
The integer promotions are performed on each of the operands. The type of
the result is
that of the promoted left operand. If the value of the right operand is
negative or is
greater than or equal to the width of the promoted left operand, the
behavior is undefined.
"""
What has this to do with the question at hand? It would
have made equal sense to quote the description of setvbuf().
But unless you use a brain-damaged compiler, this is the usual behaviour,
though not "Standard". Now I wait for quibblings and their crazy counter
examples.


What is "this" that you say is "usual behavior?" (And why
is is "quibbling" to point out that you are wrong Yet Again?
"All people with French-ish names are three meters tall and
have five eyes on wavy stalks; don't bother me with crazy
counter-examples.")

--
Er*********@sun.com

Nov 14 '05 #14
Ok, mea culpa:
Only your latest -- and, I fear, probably not your last.


Only the first, and hopefully not my last. I don't believe I understand
everything, did you think so ? I thought NG were to share fruitful
discussions and informations. Maybe you believe I'm not able to
do that, but you're not proving you are in this whole post. Sadly.
What has this to do with the question at hand? It would
have made equal sense to quote the description of setvbuf().
2nd mea culpa :-) It was a copy/paste mistake this time, but I already
answered.
What is "this" that you say is "usual behavior?" (And why
Really you have no idea ? Never mind.
is is "quibbling" to point out that you are wrong Yet Again? "All people with French-ish names are three meters tall and
have five eyes on wavy stalks; don't bother me with crazy
counter-examples."


Ah Ah Ah. We have tons of anti-US jokes, but I don't think
it would be a high mark of intellingence to put them on that
newsgroup.

Nov 14 '05 #15
Villy Kruse wrote:

On Wed, 15 Jun 2005 13:58:59 GMT,
pete <pf*****@mindspring.com> wrote:

If you want an arithmetic shift, then use an arithmetic operator.

integer /= 2


Carefull with negative integers.

#include <stdlib.h>
#include <stdio.h>

int main ()
{
printf("%x\n", -1235);
printf("%x\n", -1235 / 2);
printf("%x\n", -1235 >> 1);
return 0;
}


As far as getting an arithmetic shift goes, dividing by two
*does* get an arithmetic shift for negative integers, always.

But, you just reminded me that some negative division itself,
what the arithmetic shift is, is implementation defined in C89.

ISO/IEC 9899: 1990
6.3.5 Multiplicative operators

If either operand is negative,
whether the result of the / operator is the
largest integer less than or equal to the algebraic quotient
or the smallest integer greater than
or equal to the algebraic quotient is implementation-defined,
as is the sign of the result of the % operator.
If the quotient a/b is representable,
the expression (a/b)*b + a%b shall equal a.

--
pete
Nov 14 '05 #16
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. Anything else can lead to undefined and
implementation defined behaviour.

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

If there are appropriate shifting sequences available on the end
machine, the compiler optimizer has the job of finding them. Not
you.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #17


pete wrote:
Villy Kruse wrote:
On Wed, 15 Jun 2005 13:58:59 GMT,
pete <pf*****@mindspring.com> wrote:

If you want an arithmetic shift, then use an arithmetic operator.

integer /= 2

Carefull with negative integers.

#include <stdlib.h>
#include <stdio.h>

int main ()
{
printf("%x\n", -1235);
printf("%x\n", -1235 / 2);
printf("%x\n", -1235 >> 1);
return 0;
}

As far as getting an arithmetic shift goes, dividing by two
*does* get an arithmetic shift for negative integers, always.


Well, not exactly. On two's complement systems, -1 right-
shifted with sign propagation equals -1, but -1 / 2 is zero
(under C99 rules).
But, you just reminded me that some negative division itself,
what the arithmetic shift is, is implementation defined in C89.

ISO/IEC 9899: 1990
6.3.5 Multiplicative operators

If either operand is negative,
whether the result of the / operator is the
largest integer less than or equal to the algebraic quotient
or the smallest integer greater than
or equal to the algebraic quotient is implementation-defined,
as is the sign of the result of the % operator.
If the quotient a/b is representable,
the expression (a/b)*b + a%b shall equal a.


Yes: C90 permitted the implementation to choose, and
provided the div() and ldiv() functions when predictable
behavior was needed. C99 eliminated the choice, but div()
and ldiv() -- and now lldiv()! -- are still with us.

<off-topic excuse="intriguing trivia">

According to the Rationale, the choice was eliminated to
make C99 comply with Fortran's rules for arithmetic. Ponder
this next time somebody sneers about "dead languages" -- and
ponder, too, how some of C's weirdnesses are perpetuated in
Java. "But we've always done it that way" has more force
than we may like to admit.

</off-topic>

--
Er*********@sun.com

Nov 14 '05 #18
Eric Sosman wrote:

pete wrote:
Villy Kruse wrote:
On Wed, 15 Jun 2005 13:58:59 GMT,
pete <pf*****@mindspring.com> wrote:
If you want an arithmetic shift, then use an arithmetic operator.

integer /= 2
Carefull with negative integers.

#include <stdlib.h>
#include <stdio.h>

int main ()
{
printf("%x\n", -1235);
printf("%x\n", -1235 / 2);
printf("%x\n", -1235 >> 1);
return 0;
}

As far as getting an arithmetic shift goes, dividing by two
*does* get an arithmetic shift for negative integers, always.


Well, not exactly.
On two's complement systems,
-1 right-shifted with sign propagation equals -1,
but -1 / 2 is zero (under C99 rules).


I did some googling.
It turns out that an arithmetic shift,
isn't exactly what I thought it was.

--
pete
Nov 14 '05 #19
In article <42***************@news.xs4all.nl> rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Jean-Claude Arbaut <je****************@laposte.net> wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, «*Mehta
Shailendrakumar*» <sh*******************@de.bosch.com> 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/
Nov 14 '05 #20
In article <sl****************@station02.ohout.pharmapartners .nl> nobody writes:
On Wed, 15 Jun 2005 13:58:59 GMT,
pete <pf*****@mindspring.com> wrote: ....
If you want an arithmetic shift, then use an arithmetic operator.
integer /= 2


Carefull with negative integers.


Indeed.
printf("%x\n", -1235 >> 1);


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/
Nov 14 '05 #21
In article <II********@cwi.nl> some idiot babbled:
In article <42***************@news.xs4all.nl> rl*@hoekstra-uitgeverij.nl (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/
Nov 14 '05 #22
CBFalconer <cb********@yahoo.com> 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
Nov 14 '05 #23
Jean-Claude Arbaut wrote:
Le 15/06/2005 16:27, dans d8**********@malatesta.hpl.hp.com, « Chris
Dollin » <ke**@hpl.hp.com> a écrit :
Jean-Claude Arbaut wrote:
Le 15/06/2005 15:43, dans d8*********@ns2.fe.internet.bosch.com, « Mehta
Shailendrakumar » <sh*******************@de.bosch.com> 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.
Nov 14 '05 #24

Le 16/06/2005 09:55, dans d8*********@malatesta.hpl.hp.com, «*Chris Dollin*»
<ke**@hpl.hp.com> 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 ?

Nov 14 '05 #25
On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
CBFalconer <cb********@yahoo.com> 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
Nov 14 '05 #26
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.

Nov 14 '05 #27
Lawrence Kirby wrote:

On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
CBFalconer <cb********@yahoo.com> 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
Nov 14 '05 #28
Jean-Claude Arbaut wrote:
Le 16/06/2005 09:55, dans d8*********@malatesta.hpl.hp.com, « Chris Dollin
» <ke**@hpl.hp.com> 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.
Nov 14 '05 #29


Lawrence Kirby wrote:
On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:

CBFalconer <cb********@yahoo.com> 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.

--
Er*********@sun.com

Nov 14 '05 #30

Le 16/06/2005 18:01, dans d8**********@news1brm.Central.Sun.COM, «*Eric
Sosman*» <er*********@sun.com> a écrit*:
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:


I wouldn't agree with somebody just because of its name ;-)
Just as I would not agree with a math proof just because
a great mathematician has written it.

Still, Lawrence Kirby advice are more than interesting...

Nov 14 '05 #31
On Thu, 16 Jun 2005 12:41:04 +0200, Jean-Claude Arbaut wrote:

....
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.


The point remains the same, the code demonstrates a difference between
division and arithmetic shifting.

Lawrence
Nov 14 '05 #32
Lawrence Kirby <lk****@netactive.co.uk> writes:
On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
CBFalconer <cb********@yahoo.com> wrote:
[snip]

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.


Are we reading different documents? The description I read of the
"Bitwise shift operators" (ISO/IEC 9899:1999 (E), section 6.5.7) talks
only about values, not about representations.
Nov 14 '05 #33
On Thu, 16 Jun 2005 10:51:50 -0700, Tim Rentsch wrote:

....
Are we reading different documents? The description I read of the
"Bitwise shift operators" (ISO/IEC 9899:1999 (E), section 6.5.7) talks
only about values, not about representations.


It talks abouyt thinks like "bit positions" which is a description of
representation rather than value.

Lawrence
Nov 14 '05 #34
On Thu, 16 Jun 2005 12:01:56 -0400, Eric Sosman wrote:

....
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.
You're making a distinction there but it is one that makes a
difference?
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.
I certainly agree that the standard is talking about non-padding
bits. But given that is this abstract representation you'rer
referring to any different from the underlying object
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.
Agreed. And the representation of an integer type on a particular
platform must attribute binary weightings to the value bits.
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.
I see no inconsistency in assuming that it does.
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.


Absolutely. The standard defines the shift in terms of representation.
Under the conditions this implies a well-defined numerical result it
specifies that as well.

Lawrence

Nov 14 '05 #35
Lawrence Kirby <lk****@netactive.co.uk> writes:
On Thu, 16 Jun 2005 10:51:50 -0700, Tim Rentsch wrote:

...
Are we reading different documents? The description I read of the
"Bitwise shift operators" (ISO/IEC 9899:1999 (E), section 6.5.7) talks
only about values, not about representations.


It talks abouyt thinks like "bit positions" which is a description of
representation rather than value.


It seems clear from context in the rest of the paragraph that these
phrases refer to bit positions of the value, not bit positions of the
representation. Yes? If it isn't clear then perhaps the language
should be changed to reflect that, because it seems obvious that this
interpretation is what was intended.

6.5.7

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
bits are filled with zeros. If E1 has an unsigned type, the value of
the result is E1 x 2**E2, reduced modulo one more than the maximum
value representable in the result type. If E1 has a signed type and a
nonnegative value, and E1 x 2**E2 is representable in the result type,
then that is the resulting value; otherwise, the behavior is
undefined.

5 The result of E1 >> E2 is 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 / 2**E2. If E1 has signed type and a negative value, the resulting
value is implementation-defined.
Nov 14 '05 #36

Le 16/06/2005 20:11, dans pa****************************@netactive.co.uk,
«*Lawrence Kirby*» <lk****@netactive.co.uk> a écrit*:
On Thu, 16 Jun 2005 12:41:04 +0200, Jean-Claude Arbaut wrote:

...

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.


The point remains the same, the code demonstrates a difference between
division and arithmetic shifting.

Yes, of course. I would not try to beat you on your territory ;-)

Nov 14 '05 #37
Eric Sosman <er*********@sun.com> wrote:
Lawrence Kirby wrote:
On Thu, 16 Jun 2005 07:15:58 +0000, Richard Bos wrote:
CBFalconer <cb********@yahoo.com> wrote:

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.


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.


That's a non-issue, really, and not what I wrote. Since the
representation of non-negative integers is pretty well fixed, at least
in the way that the definition of the << and >> operators do, you could
say that they work on representations as much as on values.
However, what Mr. Kirby wrote, and what I objected to, is that shifts
operate on _objects_. They don't do that; which can be proved quite
simply by noting that you can shift constants.

Richard
Nov 14 '05 #38
On Fri, 17 Jun 2005 09:18:05 +0000, Richard Bos wrote:

....
That's a non-issue, really, and not what I wrote. Since the
representation of non-negative integers is pretty well fixed, at least
in the way that the definition of the << and >> operators do, you could
say that they work on representations as much as on values.
However, what Mr. Kirby wrote, and what I objected to, is that shifts
operate on _objects_. They don't do that; which can be proved quite
simply by noting that you can shift constants.


I'm not saying shifts work on objects (I don't think I did but if so that
was a mistake), I'm saying that they work at a representation level.

Lawrence
Nov 14 '05 #39
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Fri, 17 Jun 2005 09:18:05 +0000, Richard Bos wrote:
However, what Mr. Kirby wrote, and what I objected to, is that shifts
operate on _objects_.


I'm not saying shifts work on objects (I don't think I did but if so that
was a mistake), I'm saying that they work at a representation level.


True. It wasn't you who brought up objects, it was Mr. Falconer. My
excuses.

Richard
Nov 14 '05 #40
>On Thu, 16 Jun 2005 10:51:50 -0700, Tim Rentsch wrote:
Are we reading different documents? The description I read of the
"Bitwise shift operators" (ISO/IEC 9899:1999 (E), section 6.5.7) talks
only about values, not about representations.

In article <pa****************************@netactive.co.uk>
Lawrence Kirby <lk****@netactive.co.uk> wrote:It talks abouyt thinks like "bit positions" which is a description of
representation rather than value.


I think perhaps the confusion comes in because this is a description
of "a" representation, and not necessarily "the" representation.
That is, the machine could have obnoxious padding bits in the way;
but if so, they do not participate in the value-bit-shifting.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.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 14 '05 #41
Richard Bos wrote:
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Fri, 17 Jun 2005 09:18:05 +0000, Richard Bos wrote:
However, what Mr. Kirby wrote, and what I objected to, is that
shifts operate on _objects_.


I'm not saying shifts work on objects (I don't think I did but
if so that was a mistake), I'm saying that they work at a
representation level.


True. It wasn't you who brought up objects, it was Mr. Falconer.
My excuses.


Whatever you're accusing me of, I didn't do it.

--
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
Nov 14 '05 #42
CBFalconer wrote:

Whatever you're accusing me of, I didn't do it.


"I wasn't there."
-- Pooh-Bah, "The Mikado"

--
Eric Sosman
es*****@acm-dot-org.invalid

Nov 14 '05 #43
In comp.lang.c you wrote:
Richard Bos wrote:
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Fri, 17 Jun 2005 09:18:05 +0000, Richard Bos wrote:

However, what Mr. Kirby wrote, and what I objected to, is that
shifts operate on _objects_.

I'm not saying shifts work on objects (I don't think I did but
if so that was a mistake), I'm saying that they work at a
representation level.
True. It wasn't you who brought up objects, it was Mr. Falconer.
My excuses.


Whatever you're accusing me of, I didn't do it.


I'm accusing you of writing this:
Shift operations in C are only portable, and properly defined, on
unsigned objects.


and you did (<42***************@yahoo.com>).

I'm quite willing to accept your innocence in general, of course, you
sweet, unsuspecting darling, you :-P.

Richard
Nov 14 '05 #44

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.