[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

FAQ: int or long int?

pozz

4/1/2011 9:28:00 AM

I'm interested to write portable code on embedded 16- or 32-bits
platform.
So I'm wondering which integer type to use between int and long int
when I need to manage values greater than +32767 (but lower than
+2147483647)

The Question 1.1 of comp.lang.c FAQ gives a precise answer: If you
might need large values (above 32,767 or below -32,767), use long.

I imagine this is because int type could be 16-bit on some platforms,
but long must be at least 32-bit.

At the contrary, on some 32-bit platforms, int could be 32-bit and
long int could be 64-bit. In this situation, I will use 64-bit
variables to store values that could be stored just in int variables.
Apart the greater storage space in memory, also the computation will
be more complex and slower.

So I'm wondering if it could be better to use new C99 types, such as
int32_t. In this case, on 32-bit platform with 64-bit long, I'll use
the simple int for my variable...
15 Answers

China Blue Veins

4/1/2011 9:59:00 AM

0

In article <9a31982f-0eac-4444-9769-5dd02718c397@32g2000vbe.googlegroups.com>,
pozz <pozzugno@gmail.com> wrote:

> So I'm wondering if it could be better to use new C99 types, such as
> int32_t. In this case, on 32-bit platform with 64-bit long, I'll use
> the simple int for my variable...

That's what they're there for--to explicitly state the sizes when you need to
explicitly set the sizes. And if your platform doesn't include stdint.h, make
your own.

For build tools like make it's pretty easy to create the header file and then
include it.

program: int.h program.c
...

int.h:
echo >int.c '#include <stdio.h>'
echo >>int.c '#include <limits.h>'
echo >>int.c 'int main(int n,char **p) {'
echo >>int.c 'char *i8 = 0,*i16 = 0,*i32 = 0,*i64 = 0;'
echo >>int.c '#ifdef SCHAR_MAX'
echo >>int.c 'if (SCHAR_MAX==0x7F) *i8 = "char";'
echo >>int.c 'else if (SCHAR_MAX==0x7FFF) *i16 = "char";'
echo >>int.c 'else if (SCHAR_MAX==0x7FFFFFFF) *i32 = "char";'
echo >>int.c 'else if (SCHAR_MAX==0x7FFFFFFFFFFFFFFF) *i64 = "char";'
echo >>int.c '#endif'
echo >>int.c '#ifdef SHRT_MAX'
echo >>int.c 'if (SHRT_MAX==0x7F) *i8 = "short";'
echo >>int.c 'else if (SHRT_MAX==0x7FFF) *i16 = "short";'
echo >>int.c 'else if (SHRT_MAX==0x7FFFFFFF) *i32 = "short";'
echo >>int.c 'else if (SHRT_MAX==0x7FFFFFFFFFFFFFFF) *i64 = "short";'
echo >>int.c '#endif'
echo >>int.c '#ifdef INT_MAX'
echo >>int.c 'if (INT_MAX ==0x7F) *i8 = "int";'
echo >>int.c 'else if (INT_MAX==0x7FFF) *i16 = "int";'
echo >>int.c 'else if (INT_MAX==0x7FFFFFFF) *i32 = "int";'
echo >>int.c 'else if (INT_MAX==0x7FFFFFFFFFFFFFFF) *i64 = "int";'
echo >>int.c '#endif'
echo >>int.c '#ifdef LONG_MAX'
echo >>int.c 'if (LONG_MAX==0x7F) *i8 = "long";'
echo >>int.c 'else if (LONG_MAX==0x7FFF) *i16 = "long";'
echo >>int.c 'else if (LONG_MAX==0x7FFFFFFF) *i32 = "long";'
echo >>int.c 'else if (LONG_MAX==0x7FFFFFFFFFFFFFFF) *i64 = "long";'
echo >>int.c '#endif'
echo >>int.c '#ifdef LONG_LONG_MAX'
echo >>int.c 'if (LONG_LONG_MAX ==0x7F) *i8 = "long long";'
echo >>int.c 'else if (LONG_LONG_MAX==0x7FFF) *i16 = "long long";'
echo >>int.c 'else if (LONG_LONG_MAX==0x7FFFFFFF) *i32 = "long long";'
echo >>int.c 'else if (LONG_LONG_MAX==0x7FFFFFFFFFFFFFFF)'
echo >>int.c ' *i64 = "long long";'
echo >>int.c '#endif'
echo >>int.c 'if (!i64) i64 = "long long";'
echo >>int.c 'if (!i32) i32 = i64;'
echo >>int.c 'if (!i16) i16 = i32;'
echo >>int.c 'if (!i8) i8 = i16;'
echo >>int.c 'printf("#ifndef int_h"); puts("");'
echo >>int.c 'printf("#define int_h"; puts("");'
echo >>int.c 'printf("typedef signed %s int8_t;", i8); puts("");'
echo >>int.c 'printf("typedef signed %s int16_t;", i16); puts("");'
echo >>int.c 'printf("typedef signed %s int32_t;", i32); puts("");'
echo >>int.c 'printf("typedef signed %s int64_t;", i64); puts("");'
echo >>int.c 'printf("typedef unsigned %s uint8_t;", i8); puts("");'
echo >>int.c 'printf("typedef unsigned %s uint16_t;", i16); puts("");'
echo >>int.c 'printf("typedef unsigned %s uint32_t;", i32); puts("");'
echo >>int.c 'printf("typedef unsigned %s uint64_t;", i64); puts("");'
echo >>int.c 'printf("#endif"); puts("");'
echo >>int.c 'return 0;}'
cc -o int int.c
int >int.h

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. Alameda County Sheriff.

pozz

4/1/2011 10:43:00 AM

0

On 1 Apr, 11:59, China Blue Meanies <chine.b...@yahoo.com> wrote:
>  pozz <pozzu...@gmail.com> wrote:
> > So I'm wondering if it could be better to use new C99 types, such as
> > int32_t. In this case, on 32-bit platform with 64-bit long, I'll use
> > the simple int for my variable...
>
> That's what they're there for--to explicitly state the sizes when you need to
> explicitly set the sizes. And if your platform doesn't include stdint.h, make
> your own.

At the contrary, if I use
int16_t x;
on a 32-bit platform, I'll use a non optimized type...

In both cases (long int or int16_t) I can have some drawbacks.

Ben Bacarisse

4/1/2011 11:04:00 AM

0

pozz <pozzugno@gmail.com> writes:

> On 1 Apr, 11:59, China Blue Meanies <chine.b...@yahoo.com> wrote:
>>  pozz <pozzu...@gmail.com> wrote:
>> > So I'm wondering if it could be better to use new C99 types, such as
>> > int32_t. In this case, on 32-bit platform with 64-bit long, I'll use
>> > the simple int for my variable...
>>
>> That's what they're there for--to explicitly state the sizes when you need to
>> explicitly set the sizes. And if your platform doesn't include stdint.h, make
>> your own.
>
> At the contrary, if I use
> int16_t x;
> on a 32-bit platform, I'll use a non optimized type...
>
> In both cases (long int or int16_t) I can have some drawbacks.

That is what the int_fastN_t types are for (and unlike the intN_t types
they are required by C99).

--
Ben.

Ben Bacarisse

4/1/2011 11:10:00 AM

0

China Blue Meanies <chine.bleu@yahoo.com> writes:
<snip>
> For build tools like make it's pretty easy to create the header file and then
> include it.
>
> program: int.h program.c
> ...
>
> int.h:
> echo >int.c '#include <stdio.h>'
> echo >>int.c '#include <limits.h>'
> echo >>int.c 'int main(int n,char **p) {'
> echo >>int.c 'char *i8 = 0,*i16 = 0,*i32 = 0,*i64 = 0;'
> echo >>int.c '#ifdef SCHAR_MAX'
> echo >>int.c 'if (SCHAR_MAX==0x7F) *i8 = "char";'

I think you mean i8 rather than *i8 here (and in 19 similar cases
below).

<snip>
> echo >>int.c 'printf("#define int_h"; puts("");'

missing )

<snip>
--
Ben.

China Blue Veins

4/1/2011 12:04:00 PM

0

In article <a27eaf4e-1ad5-4fc0-8ab0-a58e7bbb8b7b@w6g2000vbo.googlegroups.com>,
pozz <pozzugno@gmail.com> wrote:

> On 1 Apr, 11:59, China Blue Meanies <chine.b...@yahoo.com> wrote:
> >  pozz <pozzu...@gmail.com> wrote:
> > > So I'm wondering if it could be better to use new C99 types, such as
> > > int32_t. In this case, on 32-bit platform with 64-bit long, I'll use
> > > the simple int for my variable...
> >
> > That's what they're there for--to explicitly state the sizes when you need
> > to
> > explicitly set the sizes. And if your platform doesn't include stdint.h,
> > make
> > your own.
>
> At the contrary, if I use
> int16_t x;
> on a 32-bit platform, I'll use a non optimized type...

If that matters, then you don't want to specify an exactly 16 bit integer.

> In both cases (long int or int16_t) I can have some drawbacks.

How about int_fast16_t or int_least16_t?

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. Alameda County Sheriff.

christian.bau

4/1/2011 4:02:00 PM

0

On Apr 1, 10:28 am, pozz <pozzu...@gmail.com> wrote:

> At the contrary, on some 32-bit platforms, int could be 32-bit and
> long int could be 64-bit. In this situation, I will use 64-bit
> variables to store values that could be stored just in int variables.
> Apart the greater storage space in memory, also the computation will
> be more complex and slower.

Name a platform where long = 64 bit, int = 32 bit, and computations
using long will be more complex and slower than the same computation
using int. In my experience it is the opposite.

Ben Pfaff

4/1/2011 4:25:00 PM

0

pozz <pozzugno@gmail.com> writes:

> I'm interested to write portable code on embedded 16- or 32-bits
> platform.
> So I'm wondering which integer type to use between int and long int
> when I need to manage values greater than +32767 (but lower than
> +2147483647)

int_least32_t if you want to optimize for space.
int_fast32_t if you want to optimize for time.
--
Ben Pfaff
http://be...

Ben Bacarisse

4/1/2011 5:05:00 PM

0

"christian.bau" <christian.bau@cbau.wanadoo.co.uk> writes:

> On Apr 1, 10:28 am, pozz <pozzu...@gmail.com> wrote:
>
>> At the contrary, on some 32-bit platforms, int could be 32-bit and
>> long int could be 64-bit. In this situation, I will use 64-bit
>> variables to store values that could be stored just in int variables.
>> Apart the greater storage space in memory, also the computation will
>> be more complex and slower.
>
> Name a platform where long = 64 bit, int = 32 bit, and computations
> using long will be more complex and slower than the same computation
> using int. In my experience it is the opposite.

At first glance, it seems to be the case on my Linux system:

$ cat time.c
#include <stdio.h>
#include <limits.h>

#define STR(x) XSTR(x)
#define XSTR(x) #x

ITYPE f(ITYPE x, ITYPE y)
{
return (x * y) / (x + y);
}

int main(void)
{
printf("%s is %zu bits\n", STR(ITYPE), CHAR_BIT * sizeof(ITYPE));
ITYPE r = 1;
for (ITYPE i = 0; i < 10000; i++)
for (ITYPE j = 1; j < 10000; j++)
r = (r << 3) | f(i, j);
printf("%d", (int)r);
return 0;
}
$ gcc -DITYPE=int -std=c99 -pedantic -O3 -o time time.c
$ time ./time
int is 32 bits
-65
real 0m0.399s
user 0m0.400s
sys 0m0.000s
$ gcc -DITYPE=long -std=c99 -pedantic -O3 -o time time.c
$ time ./time
long is 64 bits
-65
real 0m1.306s
user 0m1.310s
sys 0m0.000s

I am very wary of crude timing like this, but it's a start.

--
Ben.

Eric Sosman

4/2/2011 12:52:00 AM

0

On 4/1/2011 12:01 PM, christian.bau wrote:
> On Apr 1, 10:28 am, pozz<pozzu...@gmail.com> wrote:
>
>> At the contrary, on some 32-bit platforms, int could be 32-bit and
>> long int could be 64-bit. In this situation, I will use 64-bit
>> variables to store values that could be stored just in int variables.
>> Apart the greater storage space in memory, also the computation will
>> be more complex and slower.
>
> Name a platform where long = 64 bit, int = 32 bit, and computations
> using long will be more complex and slower than the same computation
> using int. In my experience it is the opposite.

"All."

Argument: Memory access dominates all other operations in a
system; that is why the system has two or three or maybe even more
levels of very complex, very expensive cache. Those caches can hold
only half as many 64-bit objects as 32-bit objects, roughly speaking,
so if you use a 64-bit datum where a 32- or 16- or 8-bit datum would
have sufficed, you increase the "pressure" on the caches and diminish
their effectiveness. This can slow the system down dramatically: A
2GHz CPU that generates a fresh memory reference every 0.5 ns will
s--t--a--l--l for five hundred to a thousand cycles on each cache
miss. If you reduce the cache hit rate from 99% to 98% you *double*
the likelihood of such stalls; roughly speaking, you cut the rate of
"useful work" by half.

See the highly instructive lecture video by Cliff Click at
<http://www.infoq.com/presentations/click-crash-course-modern-ha....

--
Eric Sosman
esosman@ieee-dot-org.invalid

Ian Collins

4/2/2011 1:26:00 AM

0

On 04/ 2/11 01:52 PM, Eric Sosman wrote:
> On 4/1/2011 12:01 PM, christian.bau wrote:
>> On Apr 1, 10:28 am, pozz<pozzu...@gmail.com> wrote:
>>
>>> At the contrary, on some 32-bit platforms, int could be 32-bit and
>>> long int could be 64-bit. In this situation, I will use 64-bit
>>> variables to store values that could be stored just in int variables.
>>> Apart the greater storage space in memory, also the computation will
>>> be more complex and slower.
>>
>> Name a platform where long = 64 bit, int = 32 bit, and computations
>> using long will be more complex and slower than the same computation
>> using int. In my experience it is the opposite.
>
> "All."

Under some conditions. If the data set is small enough there should be
little difference.

The real question probably should have been "Name a 32 bit platform
where int is 32 bit and long is 64bit".

> Argument: Memory access dominates all other operations in a
> system; that is why the system has two or three or maybe even more
> levels of very complex, very expensive cache. Those caches can hold
> only half as many 64-bit objects as 32-bit objects, roughly speaking,
> so if you use a 64-bit datum where a 32- or 16- or 8-bit datum would
> have sufficed, you increase the "pressure" on the caches and diminish
> their effectiveness. This can slow the system down dramatically: A
> 2GHz CPU that generates a fresh memory reference every 0.5 ns will
> s--t--a--l--l for five hundred to a thousand cycles on each cache
> miss. If you reduce the cache hit rate from 99% to 98% you *double*
> the likelihood of such stalls; roughly speaking, you cut the rate of
> "useful work" by half.

On my Solaris system, the code Ben posted else-thread runs slightly
faster in 64 bit mode with long rather than int.

--
Ian Collins