On Tue, 15 Apr 2008 09:47:15 -0700 (PDT), aarklon@gmail.c om wrote in
comp.lang.c:
>
Is y >(8 * (sizeof(int) -1)) portable expression to find The MSB of
an unsigned integer y ??
It is absolutely not portable, even if you change 8 to CHAR_BIT.
I do a lot of work on a DSP where sizeof(char), sizeof(short), and
sizeof(int) are all 1. CHAR_BIT happens to be 16, of course, and
sizeof(long) is 2, sizeof(long long) is 4.
So on this implementation, either of the expressions:
(8 * (1 - 1))
....or:
(16 * (1 - 1))
....will not tell you anything about the MSB.
will this work in all the cases, all three of the representations C
allows:
>
1) two's complement
2) ones'complement
3) signed magnitude.
As others have stated, the representation of the signed int types in a
C implementation has nothing to do with the unsigned types.
Try this:
#include <limits.h>
#define UINT_MSB_MASK (UINT_MAX - (UINT_MAX >1))
if (some_unsigned_ int & UINT_MSB_MASK)
/* do stuff because it is set */
else
/* do stuff because it is not set */
You cannot find that by shifting since right shifting a negative value
gives an implementation defined result and left shifting a 1 in to the
MSB invokes undefined behaviour. If you want to know the sign and don't
care about negative zero then just use either <0 or >=0 as appropriate.
--
Flash Gordon
On 16 Apr, 03:08, Jack Klein <jackkl...@spam cop.netwrote:
On Tue, 15 Apr 2008 09:47:15 -0700 (PDT), aark...@gmail.c om wrote in
comp.lang.c:
Is y >(8 * (sizeof(int) -1)) portable expression to find TheMSBof
an unsigned integer y ??
>
It is absolutely notportable, even if you change 8 to CHAR_BIT.
<S N I P>
Try this:
>
#include <limits.h>
>
#define UINT_MSB_MASK (UINT_MAX - (UINT_MAX >1))
>
if (some_unsigned_ int & UINT_MSB_MASK)
/* do stuff because it is set */
else
/* do stuff because it is not set */
I think he got the parentheses wrong.
y >(CHAR_BIT * sizeof(int) - 1)
where the expression will be 1 if and only
if the MSB of y is set , seems fine to me.
But your solution looks neater and is likely
faster.
On 16 Apr, 20:18, Flash Gordon <s...@flash-gordon.me.ukwro te:
aark...@gmail.c om wrote, On 16/04/08 18:00:
>
<snip>
>
what about finding the MSB of a signed integer ?
>
You cannot find that by shifting since right shifting a negative value
gives an implementation defined result and left shifting a 1 in to the
MSB invokes undefined behaviour. If you want to know the sign and don't
care about negative zero then just use either <0 or >=0 as appropriate.
I think that by "MSB of a signed integer" he means
the bit which contributes the most to the magnitude
of the value rather than the sign bit.
I believe that a variation of Jack Klein's solution
for unsigned integers will also work in this case:
#include <limits.h>
#define INT_MSB_MASK (INT_MAX - (INT_MAX >1))
if (#include <limits.h>
#define UINT_MSB_MASK (UINT_MAX - (UINT_MAX >1))
if (some_unsigned_ int == 0)
/* do stuff because it is not set */
else if (some_signed_in t & INT_MSB_MASK)
/* do stuff because it is set */
else
/* do stuff because it is not set */
On a minority of systems, there's padding bits within integer types,
and so sizeof(integer type) won't give you the amount of value
representationa l bits.
On 19 Apr, 15:49, Spiros Bousbouras <spi...@gmail.c omwrote:
On 16 Apr, 20:18, Flash Gordon <s...@flash-gordon.me.ukwro te:
>
aark...@gmail.c om wrote, On 16/04/08 18:00:
>
<snip>
>
what about finding the MSB of a signed integer ?
>
You cannot find that by shifting since right shifting a negative value
gives an implementation defined result and left shifting a 1 in to the
MSB invokes undefined behaviour. If you want to know the sign and don't
care about negative zero then just use either <0 or >=0 as appropriate..
>
I think that by "MSB of a signed integer" he means
the bit which contributes the most to the magnitude
of the value rather than the sign bit.
>
I believe that a variation of Jack Klein's solution
for unsigned integers will also work in this case:
>
#include <limits.h>
>
#define INT_MSB_MASK (INT_MAX - (INT_MAX >1))
>
if (#include <limits.h>
>
#define UINT_MSB_MASK (UINT_MAX - (UINT_MAX >1))
>
if (some_unsigned_ int == 0)
/* do stuff because it is not set */
else if (some_signed_in t & INT_MSB_MASK)
/* do stuff because it is set */
else
/* do stuff because it is not set */
I bungled up my post above. The correct version is
#include <limits.h>
#define INT_MSB_MASK (INT_MAX - (INT_MAX >1))
if (some_signed_in t == 0)
/* do stuff because it is not set */
else if (some_signed_in t & INT_MSB_MASK)
/* do stuff because it is set */
else
/* do stuff because it is not set */
The above treats specially the value 0 in that even if it is
negative zero in an one's complement representation it still
considers the bit not to be set.
On 19 Apr, 17:14, Tomás Ó hÉilidhe <t...@lavabit.c omwrote:
On a minority of systems, there's padding bits within integer types,
and so sizeof(integer type) won't give you the amount of value
representationa l bits.
Therefore the expression y >(CHAR_BIT * sizeof(int) - 1) is not
a portable way to check if the MSB is set after all. If there is
even one padding bit the expression will always yield 0 regardless
of whether the MSB is set or not.
On Tue, 22 Apr 2008 10:45:41 -0700, Spiros Bousbouras wrote:
On 19 Apr, 17:14, Tomás Ó hÉilidhe <t...@lavabit.c omwrote:
>On a minority of systems, there's padding bits within integer types,
>and so sizeof(integer type) won't give you the amount of value
>representation al bits.
>
Therefore the expression y >(CHAR_BIT * sizeof(int) - 1) is not a
portable way to check if the MSB is set after all. If there is even one
padding bit the expression will always yield 0 regardless of whether the
MSB is set or not.
If there is any padding, (CHAR_BIT * sizeof(int) - 1) will be greater
than or equal to the width of unsigned int, meaning the behaviour is
undefined if you right-shift by that amount. The expression won't
necessarily evaluate to 0.
Comment