bitwise operator !!

C

chang

Hi .
I am surprised about this C Question answer even i am also not sharp
in C.

Programme is -:

#include<stdio.h>
void main()
{
int a= -3;

printf("%d",a>>1);
}

Here the printf value is coming :-2.
How come here the value is coming is -2. Please help me to know what
is happenning for negative value(a= -3).

Thanks for advance

Chang
 
S

s0suk3

Hi .
 I am surprised about this C Question answer even i am also not sharp
in C.

Programme is -:

#include<stdio.h>
void main()
{
        int a= -3;

        printf("%d",a>>1);

}

Here the printf value is coming :-2.
How come here the value is coming is -2. Please help me to know what
is happenning for negative value(a= -3).

It depends on how your machine stores negative numbers. If your
machine is like mine, the 32-bit integer -3 will look like this in
binary:

11111111111111111111111111111101

Then you perform a right shift on this integer. Shifting right a
negative (signed) integer is generally a bad idea because it's
implementation-defined whether 0's or 1's are added to the left. If
your machine is like mine, this right shift will add a 1 bit to the
left, and the resulting integer will look like this:

11111111111111111111111111111110

And that is -2 in decimal.

Sebastian
 
C

chang

It depends on how your machine stores negative numbers. If your
machine is like mine, the 32-bit integer -3 will look like this in
binary:

11111111111111111111111111111101

Then you perform a right shift on this integer. Shifting right a
negative (signed) integer is generally a bad idea because it's
implementation-defined whether 0's or 1's are added to the left. If
your machine is like mine, this right shift will add a 1 bit to the
left, and the resulting integer will look like this:

11111111111111111111111111111110

And that is -2 in decimal.

Sebastian- Hide quoted text -

- Show quoted text -


hi
Thanks all.

I got this idea but why this kind of system is there: -1
representating in this format 11111111111111111111111111111111?
Actually what is defination lies in this?

Thanks
Chang
 
W

Willem

chang wrote:
) I got this idea but why this kind of system is there: -1
) representating in this format 11111111111111111111111111111111?
) Actually what is defination lies in this?

Simple. Look at this calculation of zero minus one, in binary.
(I use 4 bits to keep it simple)

0000
0001 -
----
1 (carry the one)

0000
0001 -
1 (this is the carry)
----
11 (carry the one again)

0000
0001 -
1 (this is the carry)
----
111 (carry the one again)

0000
0001 -
1 (this is the carry)
----
1111 (carry the one again)

0000
0001 -
1 (this carry can't be used, it's a so-called carry overflow)
----
1111

So, the result of zero minus one, in binary, is a row of '1' bits.

(From this, it should be easy to determine what -2 is in binary.)


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
C

chang

chang wrote:

) I got this idea but why this kind of system is there: -1
) representating in this format 11111111111111111111111111111111?
) Actually what is defination lies in this?

Simple.  Look at this calculation of zero minus one, in binary.
(I use 4 bits to keep it simple)

  0000
  0001 -
  ----
     1 (carry the one)

  0000
  0001 -
    1  (this is the carry)
  ----
    11 (carry the one again)

  0000
  0001 -
   1  (this is the carry)
  ----
   111 (carry the one again)

  0000
  0001 -
  1  (this is the carry)
  ----
  1111 (carry the one again)

  0000
  0001 -
 1     (this carry can't be used, it's a so-called carry overflow)
  ----
  1111

So, the result of zero minus one, in binary, is a row of '1' bits.

(From this, it should be easy to determine what -2 is in binary.)

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT


Thanks .

But i am actually looking for why (-1) is represented as 0XFFFFFFFF or
in binary all bits will be 1!!!


Please guide me to know about this.

Chang
 
B

Bartc

chang said:
Thanks .

But i am actually looking for why (-1) is represented as 0XFFFFFFFF or
in binary all bits will be 1!!!

Didn't Willem just explain exactly that?

Try adding binary 000...001 to your row of 1 bits. You should get all zeros.
The same as adding 1 to -1. So -1 and all 1s are equivalent in that
encoding.

The same sometimes occurs in decimal. You might remember the old-fashioned
tape counters, which when you rewound would show 002, 001, 000, 999, ...
where you might have expected 002, 001, 000, -001,... But adding 001 to 999
gives 000, so it must be right!
 
B

Ben Bacarisse

Best not to quote sigs (the part after the "-- ").
Thanks .

But i am actually looking for why (-1) is represented as 0XFFFFFFFF or
in binary all bits will be 1!!!

That is what Willem was doing. Let me try another way (the is related
to his example). We want -1 + 1 == 0, yes? What happens to "all
ones" when we add one?
 
C

CBFalconer

chang said:
I am surprised about this C Question answer even i am also not
sharp in C.

#include<stdio.h>
void main() {
int a= -3;
printf("%d",a>>1);
}

Here the printf value is coming :-2.
How come here the value is coming is -2. Please help me to know
what is happenning for negative value(a= -3).

Attempting to shift a negative value results in either
implementation or undefined behaviour. Don't ever apply the shift
operator to a negative value. You may use division, however.
 
B

Bartc

CBFalconer said:
Attempting to shift a negative value results in either
implementation or undefined behaviour. Don't ever apply the shift
operator to a negative value. You may use division, however.

Apparently division of negative values is also implementation defined (in
C90).

-3/2 can be either -2 or -1.
 
B

Ben Bacarisse

Jujitsu Lizard said:
The other posters in this newsgroup are knuckleheads who don't
understand C, computing in general, or digital logic design.

I'll bear that in mind!
Let me help you out here.
Need to shift a signed number right 5 bits?

if (x<0)
{
result = (x >> 5) | (-1 << (sizeof(int) * 8 - 5);

You have turned simple implementation-defined behaviour into undefined
behaviour. How is that helping the OP?
}
else
{
result = ((unsigned)(x)) >> 5;

What is the point of that cast?
 
C

CBFalconer

Jujitsu said:
.... snip ...

The other posters in this newsgroup are knuckleheads who don't
understand C, computing in general, or digital logic design.
Let me help you out here.

Two's complement representation evolved so that people could use
the same instructions on signed as on unsigned operands (it is a
digital logic thing). If you work through examples carefully,
you'll see that an adder that works for signed quantities works
just fine for 2's complement quantities as well. All that
differs is flags and branches.

C does not insist on 2's complement. 1's complement, and
sign-magnitude are also completely legal. You can't use shifts on
negative quantities.
 
N

Nate Eldredge

Jujitsu Lizard said:
You've gotta be fecal mattering me. Got a citation for that? That
seems absurd.

3.3.5 Multiplicative Operators

"If either operand is negative, whether the result of the / operator is
the largest integer less than the algebraic quotient or the smallest
integer greater than the algebraic quotient is implementation-defined,
as is the sign of the result of the % operator."

C99 altered this to require a particular choice.

6.5.5 (6) "When integers are divided, the result of the / operator is
the algebraic quotient with any fractional part discarded."

So in C99, -3/2 == -1.

There was a discussion on this very topic on this group just a couple
weeks ago. I can't find it in my spool just now but Google Groups
should be able to. Basically the issue is that different machines have
divide instructions which work in different ways on negative numbers,
and C90 wanted to allow division to use the native instruction in all
cases. (Note for example that on a 16-bit machine with two's complement
arithmetic, you might expect to divide a signed integer by 2 by shifting
right by one bit, shifting in a sign bit on the left. -3 = 0xfffd,
which when shifted right gives 0xfffe = -2.) This variance was
apparently found to be inconvenient, so C99 might require some machines
to use multiple instructions (maybe a conditional jump) to get the right
behavior.
 
J

James Kuyper

Jujitsu said:
You've gotta be fecal mattering me. Got a citation for that? That
seems absurd.

I don't have a citation, because I don't have a copy of the C90
standard. However, I can explain why this was the case. There are
arguments for having either -2 or -1 as a result for -3/2. At the time
the C89 standard was written, there were many implementations that would
produce -2, and many others where it would produce -1. The standard was
therefore written to accommodate both choices.

If it's any consolation, this was changed in C99. A result of -1 is now
required. For most of my code, a value of -2 would have been better
(mainly because of what it implies for the % operator). However, having
a single required result, even if it's the "wrong" one from my point of
view, makes things easier than having two different possible results.
 
B

Ben Bacarisse

Jujitsu Lizard said:
You should, because you're one of them!

I assumed so. You made no exception to the rule.
Your job as my antagonist is to show how it is undefined. (BTW, I'm
missing a closing parenthesis, I think). What don't you understand?
What do you believe is undefined?

Shifting a signed integer to the left.
It is called "casting symmetry". If you have an if-else construct and
a cast occurs in the if() part, there must also be at least one cast
in the else part. (Translation: you are probably right.)

There is no cast in the other branch of the if. If I accepted your
symmetry rule (I don't, but that is by the by) you would need to add
one to the 'if' part.
 
N

Nate Eldredge

Jujitsu Lizard said:
Hi Ben,

I thought that shifting a signed integer to the left was perfectly
defined but shifting a signed integer to the right had the bothersome
complexity.

Am I wrong?

Yes.

6.5.7 (4-5) of the C99 standard says (paraphrasing) that a *nonnegative*
integer of a signed *type* can be shifted left or right with the
expected result. But if the value of the integer is negative, then "the
behavior is undefined" in both cases.

You might want to get yourself a copy of the standard (costs money) or a
reasonable draft thereof (free) and you can search out these details
yourself. See http://clc-wiki.net/wiki/The_C_Standard for some links.
 
C

CBFalconer

Jujitsu said:
.... snip ...


I thought that shifting a signed integer to the left was perfectly
defined but shifting a signed integer to the right had the
bothersome complexity.

Am I wrong?

Yes. Shifting a negative value left can result in sign changes
and/or overflow. That is covered in the standard as either
implementation or undefined behaviour. Don't do that.
 
F

Flash Gordon

CBFalconer wrote, On 08/12/08 01:35:
Jujitsu Lizard wrote:
... snip ...

C does not insist on 2's complement. 1's complement, and
sign-magnitude are also completely legal. You can't use shifts on
negative quantities.

It can go wrong with 2's complement machines as well. There have been
processors with only a logical shit.

However, since the behaviour is implementation defined, you can use it
as long as you read the implementation documentation to find out *how*
it is defined for that specific implementation and don't care about
portability to implementations which define it differently. I don't
think it is a good idea, but you can do it.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top