Set all bits to 1 in an array of raw bytes

M

Martin Wells

I have an array as follows:

char unsigned data[N];

I want to set every single bit in the array to 1. My initial thoughts
were:

memset(data, UCHAR_MAX, sizeof data);

but then when I looked at the declaration for memset, I saw that the
middle parameter was an int rather than an unsigned char. The problem
here is that UCHAR_MAX isn't guaranteed to "fit" in an int.

Can anyone think of a way to set all the bits to 1 (other than looping
through the elements and assigning UCHAR_MAX to them)?

Possibly, what I need is an int value that will convert to UCHAR_MAX
on every implementation... hmm...

Martin
 
I

iesvs

I have an array as follows:

char unsigned data[N];

I want to set every single bit in the array to 1. My initial thoughts
were:

memset(data, UCHAR_MAX, sizeof data);

but then when I looked at the declaration for memset, I saw that the
middle parameter was an int rather than an unsigned char. The problem
here is that UCHAR_MAX isn't guaranteed to "fit" in an int.

Can anyone think of a way to set all the bits to 1 (other than looping
through the elements and assigning UCHAR_MAX to them)?

Possibly, what I need is an int value that will convert to UCHAR_MAX
on every implementation... hmm...

Martin

If you got 2's complementary you can pass -1 which is all the bit to
1.
But some says that there is architecture where it's not a 2's
complementary (why, it's strange, have they find a better way to code
the numbers ?).
 
M

Martin Wells

If you got 2's complementary you can pass -1 which is all the bit to
1.
But some says that there is architecture where it's not a 2's
complementary (why, it's strange, have they find a better way to code
the numbers ?).


Fully-portably please as regards C89. . .

Martin
 
M

Mark Bluemel

Martin said:
I have an array as follows:

char unsigned data[N];

I want to set every single bit in the array to 1. My initial thoughts
were:

memset(data, UCHAR_MAX, sizeof data);

How about this?

memset(data,~0,sizeof data);
 
I

Ivan Gotovchits

Mark said:
How about this?

memset(data,~0,sizeof data);

It must work (except syntax errors), but maybe better, to use:

unsigned char nonzero ~0;
memset(data, nonzero, sizeof(data));
 
I

iesvs

unsigned char all1bit (void)
{
unsigned char a, b, c;
do
{
a = 2 * b + 1;
c = a;
a = b;
b = c;
} while (a != b);
return a;
}

Perhaps this. But I'm not sure.
all1bit () must return a char with all bit set to 1. (You can use it
with every type, not just unsigned char, just rewrite the function).
After you copy it every where in your array.
 
J

Joachim Schmitz

unsigned char all1bit (void)
{
unsigned char a, b, c;
do
{
a = 2 * b + 1;
pardon? double the uninitialized random b and add 1, then assign to a?
c = a;
a = b;
assign the unitialized random value of b to a?
b = c;
} while (a != b);
return a;
}

Perhaps this. But I'm not sure.
all1bit () must return a char with all bit set to 1. (You can use it
with every type, not just unsigned char, just rewrite the function).
After you copy it every where in your array.
Or am I missing the humo(u)r?

Bye, Jojo
 
R

Richard

Martin Wells said:
I have an array as follows:

char unsigned data[N];

I want to set every single bit in the array to 1. My initial thoughts
were:

memset(data, UCHAR_MAX, sizeof data);

but then when I looked at the declaration for memset, I saw that the
middle parameter was an int rather than an unsigned char. The problem
here is that UCHAR_MAX isn't guaranteed to "fit" in an int.

Why is that? Are you telling us that the standard says that an int can
be smaller than UCHAR? Since the smallest addressable unit of memory is a
byte and memset sets bytes, then surely an int will be bigger or
smaller than a byte and therefore -1 in an int in twos complement will
always be all bits set?
 
M

Martin Wells

Richard:
Why is that? Are you telling us that the standard says that an int can
be smaller than UCHAR? Since the smallest addressable unit of memory is a
byte and memset sets bytes, then surely an int will be bigger or
smaller than a byte and therefore -1 in an int in twos complement will
always be all bits set?

Here's a perfectly compliant C implementation:

CHAR_BIT = 64

sizeof(char) == sizeof(short) == sizeof(int) == sizeof(long)

(the unsigned counterparts are always the same size).

It's possible for unsigned char to have the range: 0 through 2^64 -1
and at the same time have int with the range: -2^63 through 2^63 - 1
(apologies if I'm off by one :p)

Anyway, it's certainly possible for UCHAR_MAX > INT_MAX, and that's
why unsigned char promotes to unsigned int (rather than int) on some
systems. Here's a simple test for it:

#include <limits.h>

#define PROMOTES_TO_UNSIGNED (UCHAR_MAX > INT_MAX)

Martin
 
M

Martin Wells

unsigned char all1bit (void)
{
unsigned char a, b, c;
do
{
a = 2 * b + 1;
c = a;
a = b;
b = c;
} while (a != b);
return a;

}

Perhaps this. But I'm not sure.
all1bit () must return a char with all bit set to 1. (You can use it
with every type, not just unsigned char, just rewrite the function).
After you copy it every where in your array.


No comment.

Martin
 
I

iesvs

pardon? double the uninitialized random b and add 1, then assign to a?

No I refuse to assign a variable when it's useless (useless means
useless). In this case it's useless. This work with every values
possible for b (yeah yeah, check if you're not sure, there are 256
cases if sizeof (char) == 1).
Or am I missing the humo(u)r?

That's not humor, I just was proposing my solution.
 
M

Martin Wells

Mark:
How about this?

memset(data,~0,sizeof data);

Excuse me while I think out loud...

1: 0

Type: int
Value: 0

2: ~0

Type: int
Value: Whatever all bits 1 is on this sytems (most likely -1
though)

3: (char unsigned)~0

Type: int
Value: ...I think we've already gone implementation defined.

Martin
 
J

Joachim Schmitz

No I refuse to assign a variable when it's useless (useless means
useless). In this case it's useless.
Useless, like useless? Or did you meant useless?
This work with every valuespossible for b
OK, it makes sure a is a odd.
(yeah yeah, check if you're not sure, there are 256
cases if sizeof (char) == 1).
sizeof(char) is 1 by definition, always. Guess you meant 'if CHAR_BIT == 8'

Bye, Jojo
 
I

iesvs

Useless, like useless? Or did you meant useless?

??? I don't understand.

In fact I assume that * 2 shift the bit and put a 0 in the new one and
that + 1 put this new one to 1. That's the idea behind this script.
 
I

iesvs

sizeof(char) is 1 by definition, always. Guess you meant 'if CHAR_BIT == 8'

When I code I don't assume that sizeof (char) == 1 and I'll never
assume it.
 
D

Don Bruder

Mark Bluemel said:
What syntax errors?
"sizeof data" == syntax error, "sizeof(data)" == correct syntax.
You missed a '='.


Why would this be better?

For starters, probably because it's syntactically correct, so it will
actually have a chance of compiling... (after fixing the missing "="
noted above, of course)
 
R

Richard Bos

When I code I don't assume that sizeof (char) == 1 and I'll never
assume it.

# 6.5.3.4 The sizeof operator
....
# Semantics
....
# 3 When applied to an operand that has type char, unsigned char, or
# signed char, (or a qualified version thereof) the result is 1.

Are you perhaps related to our other regular Frenchman? Your
idiosyncratic view of the language seems a match for his.

Richard
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top