size of long

P

pembed2003

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!
 
R

Régis Troadec

pembed2003 said:
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
 
K

kyle york

Greetings,

Régis Troadec said:
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.
 
J

Jarno A Wuolijoki

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;

Sure about this one?
 
R

Régis Troadec

"Jarno A Wuolijoki" <[email protected]> a écrit dans le message de

Hi,
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;

Sure about this one?

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
 
J

Jarno A Wuolijoki

Sure about this one?

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."
 
R

Régis Troadec

"Jarno A Wuolijoki" <[email protected]> a écrit dans le message de

Hi,
ul >>= CHAR_BIT;

Sure about this one?

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
 
J

Jack Klein

Greetings,



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.
 
P

pete

pembed2003 said:
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 */
 
C

Chris McDonald

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: (e-mail address removed)
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
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top