# size of long

Discussion in 'C Programming' started by pembed2003, Apr 23, 2004.

1. ### pembed2003Guest

Hi all,
As an exercise, I am trying to figure out the size of a long in my
machine without using the sizeof operator. I came up with the
following:

int size_of_long(){
long i = 1,c = 1;
while(i > 0){
i<<=1;
c++;
}
return c / 8;
}

This works fine but I am afraid that if the code is being run in a
machine where it doesn't use 2's compliment. It will not work so I
came up with another function:

int size_of_long2(){
long i[2];
return (long)(i+1) - (long)i;
}

This works regardless of what machine the code is running. I wonder if
there is any other ways to determine the size of long?

Thanks!

pembed2003, Apr 23, 2004

"pembed2003" <> a écrit dans le message de
news:...
> Hi all,

Hi,

> As an exercise, I am trying to figure out the size of a long in my
> machine without using the sizeof operator. I came up with the
> following:
>
> int size_of_long(){
> long i = 1,c = 1;
> while(i > 0){
> i<<=1;

Please don't apply bitwise shift operators on signed values (long is signed
long), even if you initialized i to 1 here. The day i will change for
example to -2, it'll be an undefined behavior.

> c++;
> }
> return c / 8;

Are you sure a byte is 8-bit with your implementation ?
CHAR_BIT will help you, it's defined in <limits.h>, as well as ULONG_MAX
(max of an unsigned long) to apply bit shitfs operations correctly. By
looking at other predefined macros, you'll be able to retrieve the sizes of
other integral types using this basic example :

#include <stdio.h>
#include <stdlib.h>

size_t sizeoflong(void)
{
unsigned long ul = ULONG_MAX;
size_t res = 0;
while (ul > 0)
{
ul >>= CHAR_BIT;
++res;
}
return res;
}

int main(void)
{
printf("sizeof(long) = %d\n", sizeoflong());
return 0;
}

Regis

3. ### kyle yorkGuest

Greetings,

>
> Are you sure a byte is 8-bit with your implementation ?
> CHAR_BIT will help you, it's defined in <limits.h>, as well as ULONG_MAX
> (max of an unsigned long) to apply bit shitfs operations correctly. By
> looking at other predefined macros, you'll be able to retrieve the sizes of
> other integral types using this basic example :
>
> #include <stdio.h>
> #include <stdlib.h>
>
> size_t sizeoflong(void)
> {
> unsigned long ul = ULONG_MAX;

I'm sure someone more knowledgable than I will correct this, but I don't
read any guarentee that unsigned long and long are the same size. Since
you're shifting a known possitive value to the right, it is fully
defined, so change:

unsigned long ul = ULONG_MAX

to

long l = LONG_MAX

you might actually get what was requested.

Of course, there's also no guarentee that the number of bits available
to a long is sizeof(LONG) * CHAR_BIT. Some bits might very well be used
for other purposes such that if sizeof(LONG) * CHAR_BIT is 45, possibly
5 of those bits aren't used.

--
Kyle A. York
Sr. Subordinate Grunt

kyle york, Apr 24, 2004

>
> #include <stdio.h>
> #include <stdlib.h>

^^^^^^
Sorry, #include <limits.h>

5. ### Jarno A WuolijokiGuest

On Sat, 24 Apr 2004, Régis Troadec wrote:

> CHAR_BIT will help you, it's defined in <limits.h>, as well as ULONG_MAX
> (max of an unsigned long) to apply bit shitfs operations correctly. By
> looking at other predefined macros, you'll be able to retrieve the sizes of
> other integral types using this basic example :

[snip]

> ul >>= CHAR_BIT;

Jarno A Wuolijoki, Apr 24, 2004

"Jarno A Wuolijoki" <> a écrit dans le message de
news...

Hi,

> On Sat, 24 Apr 2004, Régis Troadec wrote:
>
> > CHAR_BIT will help you, it's defined in <limits.h>, as well as ULONG_MAX
> > (max of an unsigned long) to apply bit shitfs operations correctly. By
> > looking at other predefined macros, you'll be able to retrieve the sizes

of
> > other integral types using this basic example :

>
> [snip]
>
> > ul >>= CHAR_BIT;

>
>

Yes : §6.2.6.1 about representation of types (C99, should also be somewhere
in C90)

"Values stored in non-bit-field objects of any other object consist of
n*CHAR_BIT bits, where n is the size of an object of that type in bytes. The
value may be copied into an object of type unsigned char[n] (e.g. by
memcpy); the resulting set of bytes is called the object representation of
the value. ..."

Regis

7. ### Jarno A WuolijokiGuest

On Sat, 24 Apr 2004, Régis Troadec wrote:

> > > ul >>= CHAR_BIT;

> >

>
> Yes : §6.2.6.1 about representation of types (C99, should also be somewhere
> in C90)
>
> "Values stored in non-bit-field objects of any other object consist of
> n*CHAR_BIT bits, where n is the size of an object of that type in bytes. The
> value may be copied into an object of type unsigned char[n] (e.g. by
> memcpy); the resulting set of bytes is called the object representation of
> the value. ..."

I was more after the following:

"[...] If the value of the right operand is negative or is greater
than or equal to the width of the promoted left operand, the behavior
is undefined."

Jarno A Wuolijoki, Apr 24, 2004

"Jarno A Wuolijoki" <> a écrit dans le message de
news...

Hi,

> On Sat, 24 Apr 2004, Régis Troadec wrote:
>
> > > > ul >>= CHAR_BIT;
> > >

> >
> > Yes : §6.2.6.1 about representation of types (C99, should also be

somewhere
> > in C90)
> >
> > "Values stored in non-bit-field objects of any other object consist of
> > n*CHAR_BIT bits, where n is the size of an object of that type in bytes.

The
> > value may be copied into an object of type unsigned char[n] (e.g. by
> > memcpy); the resulting set of bytes is called the object representation

of
> > the value. ..."

>
> I was more after the following:
>
> "[...] If the value of the right operand is negative

No problem, CHAR_BIT is positive and at least 8.

> or is greater than or equal to the width of the promoted left operand, the

behavior
> is undefined."

Mmmm...I agree that it could have led to an undefined behaviour if the width
of an unsigned long were equal to CHAR_BIT, and, actually, I haven't found
something in the standard which states that sizeof(long) is greater than
sizeof(char). Nevertheless, it is the case with most of systems.

Regis

9. ### Jack KleinGuest

On Fri, 23 Apr 2004 16:46:06 -0700, kyle york <> wrote
in comp.lang.c:

> Greetings,
>
> >
> > Are you sure a byte is 8-bit with your implementation ?
> > CHAR_BIT will help you, it's defined in <limits.h>, as well as ULONG_MAX
> > (max of an unsigned long) to apply bit shitfs operations correctly. By
> > looking at other predefined macros, you'll be able to retrieve the sizes of
> > other integral types using this basic example :
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > size_t sizeoflong(void)
> > {
> > unsigned long ul = ULONG_MAX;

>
> I'm sure someone more knowledgable than I will correct this, but I don't
> read any guarentee that unsigned long and long are the same size. Since
> you're shifting a known possitive value to the right, it is fully
> defined, so change:

The standard requires that they be exactly the same size:

"For each of the signed integer types, there is a corresponding (but
different) unsigned integer type (designated with the keyword
unsigned) that uses the same amount of storage (including sign
information) and has the same alignment requirements."

> unsigned long ul = ULONG_MAX
>
> to
>
> long l = LONG_MAX

The signed variety of each integer type generally has one fewer bits
than the unsigned type, although the standard allows them to have the
same. I don't know of any hardware architecture that ever worked this
way, but there might well have been one somewhere.

In general, LONG_MAX is equal to ULONG_MAX >> 1.

> you might actually get what was requested.
>
>
> Of course, there's also no guarentee that the number of bits available
> to a long is sizeof(LONG) * CHAR_BIT. Some bits might very well be used
> for other purposes such that if sizeof(LONG) * CHAR_BIT is 45, possibly
> 5 of those bits aren't used.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

Jack Klein, Apr 25, 2004
10. ### peteGuest

pembed2003 wrote:
>
> Hi all,
> As an exercise, I am trying to figure out the size of a long in my
> machine without using the sizeof operator. I came up with the
> following:

> int size_of_long2(){
> long i[2];
> return (long)(i+1) - (long)i;
> }
>
> This works regardless of what machine the code is running. I wonder if
> there is any other ways to determine the size of long?

/* BEGIN longsize.c */

#include <stdio.h>

size_t size_of_long3(void)
{
long integer;

return (char*)(&integer + 1) - (char*)&integer;
}

int main(void)
{
printf("sizeof(long) is %lu.\n", (long unsigned)size_of_long3());
return 0;
}

/* END longsize.c */

--
pete

pete, Apr 25, 2004
11. ### Chris McDonaldGuest

>pembed2003 wrote:
>>
>> Hi all,
>> As an exercise, I am trying to figure out the size of a long in my
>> machine without using the sizeof operator. I came up with the
>> following:

Why does this newsgroup receive so many questions wishing to perform
tasks without the use of the standard C facilities? Not all of these
questions can be homework questions.

What, here, is wrong with the sizeof operator?
Yesterday it was sorting a vector of integers without using 'if' statements!

_______________________________________________________________________________
Dr Chris McDonald EMAIL:
School of Computer Science & Software Engineering
The University of Western Australia WWW: http://www.csse.uwa.edu.au/~chris
Crawley, Western Australia, 6009 PH: +61 8 6488 2533, FAX: +61 8 6488 1089

Chris McDonald, Apr 25, 2004