Velocity Reviews > Bitshifting independant of signedness

# Bitshifting independant of signedness

Frederick Gotham
Guest
Posts: n/a

 08-24-2006

Just wondering if bitwise operators pay any attention to the signedness of
an integer type? Do they pay any attention to, or work any differently
with, the sign-bit, or with a signed integer type?

Let's take a hypothetical system where:

(1) int is comprised of 32 value bits (inclusive of the sign-bit).
(2) Two's complement is used.

The bit-pattern for -18 on such a system is:

1111 1111 1111 1111 1111 1111 1110 1110

On such a system is the following *guaranteed* to work?

#define VALBITS_INT 31
/* The above figure does NOT
inlude the sign bit. */

int Minus18()
{
int i = 0;

/* (1) First set the sign-bit: */

i |= 1U << VALBITS_INT;
/* Will this definitely set the sign-bit?
Is the U tag necessary on the literal? */

/* (2) Set all other bits to 1: */

int const MSBonly = 1 << VALBITS_INT-1;

i |= MSBonly | MSBonly-1;

/* (3) Toggle first and fifth bits */

i ^= 1;
i ^= 16;

return i;
}

When performing a bitwise operation, are the integer types treated as if
they're unsigned?

--

Frederick Gotham

Michael Mair
Guest
Posts: n/a

 08-24-2006
Frederick Gotham schrieb:
> Just wondering if bitwise operators pay any attention to the signedness of
> an integer type? Do they pay any attention to, or work any differently
> with, the sign-bit, or with a signed integer type?
>
> Let's take a hypothetical system where:
>
> (1) int is comprised of 32 value bits (inclusive of the sign-bit).
> (2) Two's complement is used.

(3) You assume that there are no padding bits in signed int
that are not also there in unsigned int.
(4) You assume that INT_MAX+1U != 0 (the "and vice versa"
part for (3))

> The bit-pattern for -18 on such a system is:
>
> 1111 1111 1111 1111 1111 1111 1110 1110
>
> On such a system is the following *guaranteed* to work?
>
> #define VALBITS_INT 31
> /* The above figure does NOT
> inlude the sign bit. */
>
> int Minus18()
> {
> int i = 0;
>
> /* (1) First set the sign-bit: */
>
> i |= 1U << VALBITS_INT;
> /* Will this definitely set the sign-bit?
> Is the U tag necessary on the literal? */

Depends. The 1U will be detrimental if (4) does not hold as
you would then shift "too far".

>
> /* (2) Set all other bits to 1: */
>
> int const MSBonly = 1 << VALBITS_INT-1;
>
> i |= MSBonly | MSBonly-1;

Will not set all bits if (3) does not hold.
i = ~0;
certainly works better in that respect.

>
> /* (3) Toggle first and fifth bits */
>
> i ^= 1;
> i ^= 16;
>
> return i;
> }
>
> When performing a bitwise operation, are the integer types treated as if
> they're unsigned?

No. Note that you could "assemble" the representation and then
reinterpret it:
int i;
unsigned int u = -1;
unsigned neg = 18;
u ^= (neg - 1U);
i = *(int *)&u;
This needs (1) to (4) as well.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

pete
Guest
Posts: n/a

 08-24-2006
Frederick Gotham wrote:
>
> Just wondering if bitwise operators pay any attention to the signedness of
> an integer type? Do they pay any attention to, or work any differently
> with, the sign-bit, or with a signed integer type?
>
> Let's take a hypothetical system where:
>
> (1) int is comprised of 32 value bits (inclusive of the sign-bit).
> (2) Two's complement is used.
>
> The bit-pattern for -18 on such a system is:
>
> 1111 1111 1111 1111 1111 1111 1110 1110
>
> On such a system is the following *guaranteed* to work?
>
> #define VALBITS_INT 31
> /* The above figure does NOT
> inlude the sign bit. */
>
> int Minus18()
> {
> int i = 0;
>
> /* (1) First set the sign-bit: */
>
> i |= 1U << VALBITS_INT;
> /* Will this definitely set the sign-bit?
> Is the U tag necessary on the literal? */

I think your attempt is undefined.

>
> /* (2) Set all other bits to 1: */
>
> int const MSBonly = 1 << VALBITS_INT-1;
>
> i |= MSBonly | MSBonly-1;
>
> /* (3) Toggle first and fifth bits */
>
> i ^= 1;
> i ^= 16;
>
> return i;
> }
>
> When performing a bitwise operation,
> are the integer types treated as if
> they're unsigned?

No.

Setting the sign bit with a left shift, looks undefined to me.

N869
6.5.7 Bitwise shift operators

[#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×2E2, reduced
modulo one more than the maximum value representable in the
result type. If E1 has a signed type and nonnegative value,
and E1×2E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.

--
pete

Frederick Gotham
Guest
Posts: n/a

 08-25-2006
Michael Mair posted:

> (3) You assume that there are no padding bits in signed int
> that are not also there in unsigned int.

I said it had 32 value bits, not 32 object bits.

--

Frederick Gotham

Michael Mair
Guest
Posts: n/a

 08-25-2006
Frederick Gotham schrieb:
> Michael Mair posted:
>
>> (3) You assume that there are no padding bits in signed int
>> that are not also there in unsigned int.

>
> I said it had 32 value bits, not 32 object bits.

Yes. However, only the common range of unsigned int and signed
int is guaranteed to have the same representation.
I do not find anything in the standard against either
signed: sign bit -- four padding bits -- 31 value bits
unsigned: five padding bits -- 31 value bits
or
signed: sign bit -- four padding bits -- 31 value bits
unsigned: four padding bits -- 32 value bits
or
signed: sign bit -- four padding bits -- 31 value bits
unsigned: 36 value bits
or, what you were hoping for
signed: sign bit -- four padding bits -- 31 value bits
unsigned: one value bit -- four padding bits -- 31 value bits
where the above specifies the "bit order" of the representation.
So, without the stipulation that unsigned has one more value
bit than signed int and that that additional value bit is
"in the same place" as the sign bit of the signed int, your
expectations may be off.
You may shift too far for identical numbers of value bits in
the first of the above cases. Or you may fail to set the "sign
bit" in the second case.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.