Loading a variable with its maximum value

E

Eric

Consider the following code:

typedef uint32_t myType_t; // this is an UNSIGNED 32-bit type

myType_t xxx;

Now, what I want to do is load xxx with the maximum possible value
that it can hold, i.e. all bits = 1. How do I do that in a way such
that if the typedef is changed to something other than a 32-bit
unsigned, it will still work?

I can't say "xxx = 0xFFFFFFFF" because that breaks if someone changes
the typedef to "typedef uint16_t myType_t".

I can't say "xxx = -1" because xxx is an unsigned.

Can I use something like:

xxx = 0;
xxx = ~xxx; // bitwise 1's complement

.... or maybe even "xxx = ~0" (bitwise 1's complement of 0)?

Before someone says "Try it and see...", I can't do that until at
least Monday.

Thanks...
 
B

Ben Pfaff

Eric said:
Consider the following code:

typedef uint32_t myType_t; // this is an UNSIGNED 32-bit type

myType_t xxx;

Now, what I want to do is load xxx with the maximum possible value
that it can hold, i.e. all bits = 1. How do I do that in a way such
that if the typedef is changed to something other than a 32-bit
unsigned, it will still work?

xxx = -1;
I can't say "xxx = -1" because xxx is an unsigned.

Yes, you can. When a negative value is converted to a unsigned
type, it is done by adding the maximum value of the unsigned
type, plus 1, until the value is in the correct range.

Try it.
 
H

Harald van Dijk

Eric said:
Consider the following code:

typedef uint32_t myType_t; // this is an UNSIGNED 32-bit type

myType_t xxx;

Now, what I want to do is load xxx with the maximum possible value that
it can hold, i.e. all bits = 1. How do I do that in a way such that if
the typedef is changed to something other than a 32-bit unsigned, it
will still work? [...]
Can I use something like:

xxx = 0;
xxx = ~xxx; // bitwise 1's complement

Yes.

So long as the unsigned type has as much or more bits than an int, this
works as expected, otherwise you're just assigning ~(int)0 (which will
work on all systems where ~0 == -1, but for a completely different
reason). You can't perform bitwise arithmetic on types smaller than int.
 
P

Phil Carmody

Richard Heathfield said:
Eric said:


As long as its unsignedness remains unaltered, you can just say:

myType_t xxx = -1;


Right.

Erm, wrong?

xxx will be set to 0xFFFF, which is "the maximum possible value
that it can hold", as requested.

If someone changes it to a >32-bit unsigned integer type,
then it breaks. So the technique is broken, but not for
the reason given.
Er, yes, you can. If the value to be stored in an unsigned integer
type is outside the range that it can store, the value is "reduced"
(which, as in this case, can mean increasing it!) modulo one
greater than the maximum value that the type can store. So if you
have a four-bit integer type (no, I know, but four is a nice small
number), the maximum value it can store is 15. If you assign -1 to
it, it is reduced modulo 16 (i.e. 15+1). Since -1 is beneath the
relevant range, just keep adding 16s until the number becomes
positive. -1+16 = 15, and hey presto, we're done here.


Yes. Or you can cut out the middle man and say xxx = -1;

I once saw a coding standard that advised "xxx = 0-1;", to
bring attention to the fact that this wasn't actually '-1'.

Of course, this breaks if the replacement type is _signed_.

Perhaps a ternary ?: with a constant condition that compared
(myType_t)-1 with 0 and selected an appropriate expression
for the two cases? Ugly, but can be wrapped up in a static
const.

Phil
 
P

Phil Carmody

Of course, this breaks if the replacement type is _signed_.

Note - I was taking that comment literally. It _IS_ an
unsigned type. That doesn't mean it _has to be_ an unsigned
type, merely that it is. If someone's going to change
the type to a signed one, I presume he'll change the
comment too to reflect the new status.
 
C

CBFalconer

Eric said:
Consider the following code:

typedef uint32_t myType_t; // this is an UNSIGNED 32-bit type

myType_t xxx;

Now, what I want to do is load xxx with the maximum possible
value that it can hold, i.e. all bits = 1. How do I do that in
a way such that if the typedef is changed to something other
than a 32-bit unsigned, it will still work?

I can't say "xxx = 0xFFFFFFFF" because that breaks if someone
changes the typedef to "typedef uint16_t myType_t".

I can't say "xxx = -1" because xxx is an unsigned.

Yes you can. Read the standard on how unsigned values are
controlled.
 
K

Keith Thompson

Eric said:
Consider the following code:

typedef uint32_t myType_t; // this is an UNSIGNED 32-bit type

myType_t xxx;

Now, what I want to do is load xxx with the maximum possible value
that it can hold, i.e. all bits = 1. How do I do that in a way such
that if the typedef is changed to something other than a 32-bit
unsigned, it will still work?
[...]

The ideal solution would be to add a macro:

typedef uint32_t myType_t;
#define MYTYPE_MAX UINT32_MAX

and make sure you update the macro definition whenever you change the
type.

If you don't control the code that defines myType_t, of course, you
can't do this.
 
T

Tomás Ó hÉilidhe

The ideal solution would be to add a macro:

    typedef uint32_t myType_t;
    #define MYTYPE_MAX UINT32_MAX

and make sure you update the macro definition whenever you change the
type.



I consider that to be the most unideal solution. You want as little
stuff to change as possible, which is why so many people advocate
doing stuff like:

char buf[56], *p = buf;

or:

p = malloc(sizeof *p);

I say take advantage of the -1 thing, it's perfectly recognisable when
you see it.
 
H

Harald van Dijk

Actually, only more (value) bits than an int. If the unsigned type has
exactly as many value bits as signed int, signed int can hold all of its
range of values and therefore it promotes to signed int.

I was including the sign bit. A 16-bit signed int commonly holds values
from -32768 to +32767, not from -65536 to 65535. I'm thinking we're in
agreement here, but using different terminology.
 

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,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top