Arithmetic shift operation in C

  • Thread starter Mehta Shailendrakumar
  • Start date
M

Mehta Shailendrakumar

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
 
J

Jean-Claude Arbaut

Le 15/06/2005 15:22, dans [email protected], « Mehta
Shailendrakumar » said:
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.
 
T

Tim Prince

Mehta said:
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.
 
M

Mehta Shailendrakumar

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
 
P

pete

Mehta said:
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.
 
J

Jean-Claude Arbaut

Le 15/06/2005 15:43, dans [email protected], « Mehta
Shailendrakumar » said:
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 ?
 
P

pete

Mehta said:
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
 
M

Mehta Shailendrakumar

Hi,

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

Regards,
Shailendra
 
V

Villy Kruse

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
 
R

Richard Bos

Jean-Claude Arbaut said:
Le 15/06/2005 15:43, dans [email protected], « Mehta


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
 
J

Jean-Claude Arbaut

Le 15/06/2005 16:27, dans [email protected], « Chris
Dollin » said:
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.
 
J

Jean-Claude Arbaut

Le 15/06/2005 16:27, dans [email protected], « Chris
Dollin » said:
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.
"""
 
E

Eric Sosman

Jean-Claude Arbaut said:
Le 15/06/2005 16:27, dans [email protected], « Chris



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.")
 
J

Jean-Claude Arbaut

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

pete

Villy said:
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.
 
C

CBFalconer

Mehta said:
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.
 
E

Eric Sosman

pete said:
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>
 
P

pete

Eric said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top