By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,963 Members | 1,902 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,963 IT Pros & Developers. It's quick & easy.

Anyone mind reviewing my code?

P: n/a
#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned int mask;
int a = -1;
mask = 1u << (CHAR_BIT * sizeof mask - 1);
while(mask) {
putchar(a & mask ? '1' : '0');
mask>>=1u;
}

putchar('\n');

return 0;
}

I was wanting to display the underlying representation
of signed and unsigned integers. I don't think I am
invoking undefined behavior but if I am, could someone
point it out?

Also, I can only use integer types with bitwise AND
And this is a convenient way of testing against
a mask. So how would one determine the bits
set in a float or double type to display the
underlying representation in binary?

I thought about using the examples from a
previously similar question I asked.
Where the examples given displayed the bytes in hex
I was thinking maybe I could display each individual
byte by displaying those bytes in binary consecutively.
But maybe there is a more clever way?
Nov 13 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a

On Thu, 2 Oct 2003, Mantorok Redgormor wrote:

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned int mask;
int a = -1;
mask = 1u << (CHAR_BIT * sizeof mask - 1);
Undefined behavior if 'unsigned int' has any
padding bits, I think. At best, it's
implementation-defined behavior.

I believe

mask = ~0u ^ (~0u >> 1)

is guaranteed correct, although I could be
mistaken. In general, this kind of bit-twiddling
is highly representation-specific, since who
in their right minds would write bit-twiddling
code like this that *needed* to run on two different
architectures?
while(mask) {
putchar(a & mask ? '1' : '0');
mask>>=1u;
}
It would be even more portable to forget the bit
twiddling entirely, and use a recursive approach:

void print_bits(unsigned int x)
{
if (x != 0) print_bits(x/2);
printf("%d", x&1);
}
print_bits(a);

Exercise: Modify the above function to take an argument
saying how many bits to print in all.
putchar('\n');

return 0;
}
Also, I can only use integer types with bitwise AND
And this is a convenient way of testing against
a mask. So how would one determine the bits
set in a float or double type to display the
underlying representation in binary?
Examine it as an array of 'unsigned char':

double real = 3.141593;
unsigned char *representation = (unsigned char *)&real;
...
I thought about using the examples from a
previously similar question I asked.
Where the examples given displayed the bytes in hex
I was thinking maybe I could display each individual
byte by displaying those bytes in binary consecutively.
But maybe there is a more clever way?


Nope. :-)

-Arthur
Nov 13 '05 #2

P: n/a
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi**********************************@unix44. andrew.cmu.edu>...
On Thu, 2 Oct 2003, Mantorok Redgormor wrote:

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned int mask;
int a = -1;
mask = 1u << (CHAR_BIT * sizeof mask - 1);
Undefined behavior if 'unsigned int' has any
padding bits, I think.


Correct.
At best, it's implementation-defined behavior.

I believe

mask = ~0u ^ (~0u >> 1)
I'm partial to...

mask = -1u/2+1;

is guaranteed correct, although I could be
mistaken. In general, this kind of bit-twiddling
is highly representation-specific,
How many variant representations for unsigned types do you think there
are? As far as the value bits are concerned, there is only one, 'pure
binary'.
since who
in their right minds would write bit-twiddling
code like this that *needed* to run on two different
architectures?


People implementing portable encryption or coding theory algorithms
for one.

But, dumping bit-sets in most to least-significant order is not that
uncommon, or at least, I wouldn't have thought so.

--
Peter
Nov 13 '05 #3

P: n/a
Mantorok Redgormor wrote:
mask>>=1u;


That letter 'u' there doesn't help.
It doesn't hurt, but it doesn't help.

--
pete
Nov 13 '05 #4

P: n/a

On Thu, 2 Oct 2003, Peter Nilsson wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote...
On Thu, 2 Oct 2003, Mantorok Redgormor wrote:

mask = 1u << (CHAR_BIT * sizeof mask - 1);

[Something else...]
is guaranteed correct, although I could be
mistaken. In general, this kind of bit-twiddling
is highly representation-specific,
How many variant representations for unsigned types do you think there
are? As far as the value bits are concerned, there is only one, 'pure
binary'.


True. I had forgotten for a moment we were talking unsigned.
However, the numbers of value bits and padding bits are still
part of the implementation-defined representation.
since who
in their right minds would write bit-twiddling
code like this that *needed* to run on two different
architectures?


People implementing portable encryption or coding theory algorithms
for one.


While you may have a point, I think far more encryption schemes
will *assume* 32-bit 'int' or 8-bit 'char', and work with those.
Also, real code does not resort to weird bit-twiddling hacks to
produce values like 0x80000000; you'd simply write that value,
if that's what you meant. Or parameterize your coding algorithm
to specify the width of the data type being coded.
But, dumping bit-sets in most to least-significant order is not that
uncommon, or at least, I wouldn't have thought so.


True. That's why I gave the _portable_, recursive,
non-bit-twiddling solution.

-Arthur

Nov 13 '05 #5

P: n/a
On Thu, 2 Oct 2003 17:59:05 -0400 (EDT), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:

On Thu, 2 Oct 2003, Mantorok Redgormor wrote: <unsnip> I was wanting to display the underlying representation
of signed and unsigned integers. I don't think I am
invoking undefined behavior but if I am, could someone
point it out? </>
Note that none of these really display the underlying representation.
Where they work at all they display the value bits of the unsigned
value, which are (by requirement) much though possibly not all of the
representation; or of the signed value converted to unsigned, which
need not be so, although on two's-complement systems, the overwhelming
majority by far today, they are.

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned int mask;
int a = -1;
mask = 1u << (CHAR_BIT * sizeof mask - 1);


Undefined behavior if 'unsigned int' has any
padding bits, I think. At best, it's
implementation-defined behavior.

Not undefined. Shifts, like all other arithmetic operations, on
unsigned (integer) types, are well-defined. In this case, if there
are padding bits, which is i-d, the computed value will be reduced
modulo (UINT_MAX+1) to zero, which is useless.
I believe

mask = ~0u ^ (~0u >> 1)

is guaranteed correct, although I could be
mistaken. In general, this kind of bit-twiddling
is highly representation-specific, since who
in their right minds would write bit-twiddling
code like this that *needed* to run on two different
architectures?

If you really did look at the representation, that is one type,
perhaps the only type, of bit twiddling where you would have a real
need to run on different platforms.
while(mask) {
putchar(a & mask ? '1' : '0');
mask>>=1u;
}


It would be even more portable to forget the bit
twiddling entirely, and use a recursive approach:

void print_bits(unsigned int x)
{
if (x != 0) print_bits(x/2);
printf("%d", x&1);
}

Or x%2 to avoid the bitwise operators altogether and be symmetric with
/, although for unsigned types and a power of two any decent compiler
on any non-brain-damaged platform will still implement as bit ops.

And more direct and probably more efficient, putchar( x%2 +'0').

<snip>
Also, I can only use integer types with bitwise AND
And this is a convenient way of testing against
a mask. So how would one determine the bits
set in a float or double type to display the
underlying representation in binary?


Examine it as an array of 'unsigned char':

double real = 3.141593;
unsigned char *representation = (unsigned char *)&real;
...

Right.

- David.Thompson1 at worldnet.att.net
Nov 13 '05 #6

P: n/a
"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:c5********************************@4ax.com...
On Thu, 2 Oct 2003 17:59:05 -0400 (EDT), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:
unsigned int mask;
mask = 1u << (CHAR_BIT * sizeof mask - 1);


Undefined behavior if 'unsigned int' has any
padding bits, I think. At best, it's
implementation-defined behavior.

Not undefined. Shifts, like all other arithmetic operations, on
unsigned (integer) types, are well-defined. In this case, if there
are padding bits, which is i-d, the computed value will be reduced
modulo (UINT_MAX+1) to zero, which is useless.


Sorry Dave, you missed the first semantic paragraph...

Bitwise shift operators
...
The integral 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 in bits of the promoted left operand, the behavior is undefined.

Note the term 'width' is defined earlier as sign + value bits.

--
Peter
Nov 13 '05 #7

P: n/a
On Mon, 6 Oct 2003 17:37:22 +1000, "Peter Nilsson" <ai***@acay.com.au>
wrote:
"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:c5********************************@4ax.com... <snip>
> mask = 1u << (CHAR_BIT * sizeof mask - 1);
<snip> Not undefined. <snip>

Sorry Dave, you missed the first semantic paragraph... <snip>


Argh! I didn't miss it, I just forgot it. Sorry.

- David.Thompson1 at worldnet.att.net
Nov 13 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.