Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Max value of a variable

Reply
Thread Tools

Max value of a variable

 
 
Eyegor
Guest
Posts: n/a
 
      12-01-2010
Hi all,
I wonder what would be the best way to determine the maximum integer
value a variable can store if I do not know in advance the type of a
variable?

I have the following declarations:

/*Defines*/
#define AEI_unit_max 255//4294967295 /*Largest integer representable
by 32 bit AEI_unit*/

/*Type Definitions*/
typedef unsigned long AEI_unit;

I do not know in advance what the user will choose to use for
AEI_unit. common choices are 8/16/32 bit unsigned integers.
Also I do not know the target compiler, 32-bit or 64-bit compilers. I
know that different compilers treat variable differently, see:
http://en.wikipedia.org/wiki/Limits.h

my question is this:
What is the best way to assign a value to AEI_unit_max based on
AEI_unit type?

I tried to declare AEI_unit_max as a variable rather than a #define
and do the following assignment:
AEI_unit_max=(AEI_unit)(-1);
But this does not seem to work, i get gibberish from calculations
which use AEI_unit_max value.
I also tried AEI_unit_max=~0; but again no luck. Are these two methods
compiler/implementation depended? Is there a more elegant way to do
this?

Is including limits.h and using if->then statements with
sizeof(AEI_unit) be the most sure way?

Thanks
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      12-01-2010
Eyegor <(E-Mail Removed)> writes:
> I wonder what would be the best way to determine the maximum integer
> value a variable can store if I do not know in advance the type of a
> variable?
>
> I have the following declarations:
>
> /*Defines*/
> #define AEI_unit_max 255//4294967295 /*Largest integer representable
> by 32 bit AEI_unit*/
>
> /*Type Definitions*/
> typedef unsigned long AEI_unit;
>
> I do not know in advance what the user will choose to use for
> AEI_unit. common choices are 8/16/32 bit unsigned integers.
> Also I do not know the target compiler, 32-bit or 64-bit compilers. I
> know that different compilers treat variable differently, see:
> http://en.wikipedia.org/wiki/Limits.h


What exactly *do* you know? Do you know that AEI_unit is a typedef for
some unsigned integer type?

> my question is this:
> What is the best way to assign a value to AEI_unit_max based on
> AEI_unit type?
>
> I tried to declare AEI_unit_max as a variable rather than a #define
> and do the following assignment:
> AEI_unit_max=(AEI_unit)(-1);
> But this does not seem to work, i get gibberish from calculations
> which use AEI_unit_max value.


That should work. Note that the cast is unnecessary; the value -1 will
be implicitly covnerted to the type of the LHS.

> I also tried AEI_unit_max=~0; but again no luck. Are these two methods
> compiler/implementation depended? Is there a more elegant way to do
> this?


-1 should work for any unsigned type. I'm not certain that ~0 works
correctly for all possible integer representations; in any case,
-1 requires less thought.

> Is including limits.h and using if->then statements with
> sizeof(AEI_unit) be the most sure way?


This should work:

#define AEI_unit_max ((AEI_unit)-1)

and has the advantage of giving you a constant expression.

We can't tell from your description what's going wrong in your program.
If you post a complete compilable program that generates the "gibberish"
you're talking about, we can probably help.

(My best guess is that you're getting correct results but not printing
them correctly.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      12-01-2010
Eyegor <(E-Mail Removed)> writes:
>typedef unsigned long AEI_unit;


Assuming the usual implementation of integers using two's
complement encoding (untested):

max = LOG2( sizeof( AEI_UNIT ) -( ( AEI_unit )( -1 )< 0 ))- 1;

, where LOG2 needs to be defined to give the logarithm
with base 2.

 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      12-01-2010
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Stefan Ram) writes:
>Assuming the usual implementation of integers using two's
>complement encoding (untested):
>max = LOG2( sizeof( AEI_UNIT ) -( ( AEI_unit )( -1 )< 0 ))- 1;
>, where LOG2 needs to be defined to give the logarithm
>with base 2.


Sorry, that should be EXP2 and give 2 raised to the power
of the argument.

 
Reply With Quote
 
Eyegor
Guest
Posts: n/a
 
      12-01-2010
Code is in these 3 files:
http://magicmrv.com/codes/AEI/aei.c
http://magicmrv.com/codes/AEI/aei.h
http://magicmrv.com/codes/AEI/main.c

if i define AEI_max as a constant, say 255 everything works great. If
I define AEI_max by
#define AEI_unit_max ((AEI_unit)-1)
the program works as long as there is no carry over from one digit to
the next. The value of AEI_max is used in that calculation.

Does 32 lcc differentiate between long and long long ints? My guess is
that when I assign 2^32-1 to AEI_unit_max which is a 32 bit int, the
compiler also assigns 32 bits to long long int type of AEIt type, even
though i am assuming its 64 bits, which is the type i use for carry,
so it ends up being overrun.

This is what I meant a cross compiler compliance. So basically if the
compiler does not support 64 bit ints; the AEIt should be 32 bit
unsigned int and AEI_unit should be a 16 bit unsigned int, so
AEI_unit_max should be the max of 16 bit number.

If i assign unsigned short to AEI_unit and unsigned long to AEIt so
there is no compiler decision abmiguity for 32/64 bit values, and the
values are forced to 16 and 32 bits everything seems to work even
using:

#define AEI_unit_max ((AEI_unit)-1)

so I guess the question becomes: how to force the compiler to use 32
and 64 bit variables if such are supported or to use 16 and 32 bit
values if 64 bit is not supported?

Not sure if there are any standard C flags/commands, but if there are
i'd love to know about them.
Thanks
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-01-2010
Eyegor <(E-Mail Removed)> writes:
> Code is in these 3 files:
> http://magicmrv.com/codes/AEI/aei.c
> http://magicmrv.com/codes/AEI/aei.h
> http://magicmrv.com/codes/AEI/main.c


That's several hundred lines of code, and I'm frankly unwilling to wade
through it to find your problem.

Create a *small* (say, up to 20 lines) test case that exhibits the
problem you're having.

> if i define AEI_max as a constant, say 255 everything works great. If
> I define AEI_max by
> #define AEI_unit_max ((AEI_unit)-1)
> the program works as long as there is no carry over from one digit to
> the next. The value of AEI_max is used in that calculation.


In your aei.h file (I did take a quick look at it), you have:

#define AEI_unit_max (AEI_unit)-1

You're missing a set of parentheses; it needs to be:

#define AEI_unit_max ((AEI_unit)-1)

I don't know whether this is causing your problem. I'd have to
look at your calculation, which means you'd have to tell me what
it is, ideally by posting a small self-contained sample program.
(It's not unlikely that you'll solve the problem yourself in the
process of creating a small sample program.)

Upthread, you wrote:

I do not know in advance what the user will choose to use for
AEI_unit.

but AEI_unit and AEI_unit_max are defined in the same file. It looks
like *you're* defining them. If there's some mechanism for the user to
choose a type for AEI_unit, it's not reflected in your code. Is the
user expected to modify aei.h?

> Does 32 lcc differentiate between long and long long ints? My guess is
> that when I assign 2^32-1 to AEI_unit_max which is a 32 bit int, the
> compiler also assigns 32 bits to long long int type of AEIt type, even
> though i am assuming its 64 bits, which is the type i use for carry,
> so it ends up being overrun.


By "32 lcc", I'm guessing you mean lcc-win32. I think the answer
is yes; long is 32 bits and long long is 64 bits. More generally,
long is guaranteed to be at least 32 bits, and long long is at
least 64 bits, for any conforming C99 implementation.

> This is what I meant a cross compiler compliance. So basically if the
> compiler does not support 64 bit ints; the AEIt should be 32 bit
> unsigned int and AEI_unit should be a 16 bit unsigned int, so
> AEI_unit_max should be the max of 16 bit number.


You're confusing the terms "int" and "integer". "int" is one specific
integer type; it can be 16, 32, or 64 bits, among other possibilities.
There are several other integer types, including short, long, and long
long, and their unsigned variations.

I think what you're saying is that you want AEIt to be a 32-bit
unsigned integer type, and AEI_unit to be a 16-bit unsigned
integer type.

> If i assign unsigned short to AEI_unit and unsigned long to AEIt so
> there is no compiler decision abmiguity for 32/64 bit values, and the
> values are forced to 16 and 32 bits everything seems to work even
> using:
>
> #define AEI_unit_max ((AEI_unit)-1)


This is a misuse of the word "assign". I think you mean

If I define AEI_unit as unsigned short, and AEIt as unsigned long
...

> so I guess the question becomes: how to force the compiler to use 32
> and 64 bit variables if such are supported or to use 16 and 32 bit
> values if 64 bit is not supported?


Take a look at <stdint.h>. If you need an unsigned type that's exactly
32 bits, use uint32_t. (If the implementation doesn't have such a type,
uint32_t won't exist.)

Note that *all* conforming C99 implementations must support at least
one unsigned integer type that's at least 64 bits wide.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      12-01-2010
On 2010-12-01, Stefan Ram <(E-Mail Removed)-berlin.de> wrote:
> Eyegor <(E-Mail Removed)> writes:
>>typedef unsigned long AEI_unit;

>
> Assuming the usual implementation of integers using two's
> complement encoding (untested):
>
> max = LOG2( sizeof( AEI_UNIT ) -( ( AEI_unit )( -1 )< 0 ))- 1;
>
> , where ?LOG2? needs to be defined to give the logarithm
> with base 2.


Untested indeed
For AEI_UNIT=(unsigned long), UINT_MAX=4294967295, sizeof(unsigned long)=4,
that formula gives

max = LOG2(sizeof(AEI_UNIT) - ((AEI_unit)(-1) < 0)) - 1
= LOG2(4 - (4294967295 < 0)) - 1
= LOG2(4 - 0) - 1
= 2 - 1
= 1

Anyway, this topic was discussed at length in comp.lang.c just a couple of
weeks ago, and, if I remember correctly, a working solution was presented.
Check the archives.

--
(E-Mail Removed)
SDF Public Access UNIX System - http://sdf.lonestar.org
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-02-2010
On 12/1/2010 5:30 PM, Eyegor wrote:
> Code is in these 3 files:
> http://magicmrv.com/codes/AEI/aei.c
> http://magicmrv.com/codes/AEI/aei.h
> http://magicmrv.com/codes/AEI/main.c
>
> if i define AEI_max as a constant, say 255 everything works great. If
> I define AEI_max by
> #define AEI_unit_max ((AEI_unit)-1)
> the program works as long as there is no carry over from one digit to
> the next. The value of AEI_max is used in that calculation.


Based on the aei.h file, the value is correct. AEI_unit turns
out to be `unsigned', which is synonymous with `unsigned int', so
the expression `(AEI_unit)-1' is the same as `(unsigned int)-1',
which is UINT_MAX.

You've shown the AEI_unit_max definition with more parentheses
than are actually present in your header file. Since `(unsigned int)'
has a fairly high precedence this won't make a difference in any
"normal" context, but it could lead to troubles with joke code like

AEI_unit_max["1234..."]

Still, it's, unsettling to discover that you can't even copy your own
code accurately. How in the world do you expect people to help you
if you lie to them about the circumstances of your problem?

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      12-02-2010
Ike Naar <(E-Mail Removed)> writes:
>Anyway, this topic was discussed at length in comp.lang.c just a couple of
>weeks ago, and, if I remember correctly, a working solution was presented.
>Check the archives.


Thanks for the correction. I was trying to post too fast.
Sorry for the distraction. Here is another attempt.

The expression rp2() is intended to give the maximum
value of the type T.

#include <stdio.h>
#include <limits.h> /* CHAR_BIT */

#define T int

int ubits( ){ return sizeof(T)*CHAR_BIT; }
int issigned( ){ return (T)(-1)<0; }
int bits( ){ return ubits()-issigned(); }
unsigned long long rp2(){ return ~((~1ull)<<(bits()-1)); }
int main( void ){ printf( "%llu\n", rp2() ); }

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-02-2010
(E-Mail Removed)-berlin.de (Stefan Ram) writes:
> Ike Naar <(E-Mail Removed)> writes:
>>Anyway, this topic was discussed at length in comp.lang.c just a couple of
>>weeks ago, and, if I remember correctly, a working solution was presented.
>>Check the archives.

>
> Thanks for the correction. I was trying to post too fast.
> Sorry for the distraction. Here is another attempt.
>
> The expression »rp2()« is intended to give the maximum
> value of the type »T«.
>
> #include <stdio.h>
> #include <limits.h> /* CHAR_BIT */
>
> #define T int
>
> int ubits( ){ return sizeof(T)*CHAR_BIT; }
> int issigned( ){ return (T)(-1)<0; }
> int bits( ){ return ubits()-issigned(); }
> unsigned long long rp2(){ return ~((~1ull)<<(bits()-1)); }
> int main( void ){ printf( "%llu\n", rp2() ); }


But if T is known to be an unsigned type (as it seems to be in this
case), ((T)-1) works (even in the presence of padding bits).

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
want max width and max height as long as not exceed 100px Summercool HTML 9 10-23-2007 02:27 AM
ADSL Max/Max Gordy NZ Computing 6 11-24-2006 11:41 PM
Textarea max rows and max characters per row Greg Ferris Javascript 2 01-16-2004 07:21 PM
Max Apperture and Max. Shutter Speed Confusion-HELP bhaskar Digital Photography 12 07-22-2003 05:17 PM



Advertisments