range for int

P

pereges

I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:


#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);
return 0;
}

the o/p that i get:
INT_MIN:-2147483648 INT_MAX: 2147483647
LONG_MIN:-2147483648 LONG_MAX: 2147483647

basically the same thing. why is this happening ? also these ranges
seem to contradict with the one given in K & R 2. Does it have
something to do with how the numbers are represented on a particular
machine ?
 
I

Iman S. H. Suyoto

pereges said:
I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:


#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);
return 0;
}

the o/p that i get:
INT_MIN:-2147483648 INT_MAX: 2147483647
LONG_MIN:-2147483648 LONG_MAX: 2147483647

basically the same thing. why is this happening ?

Because these are the ranges your implementation can support.
> also these ranges
seem to contradict with the one given in K & R 2.

No. The ranges given in K&R2 are the minimum ones an implementation must
provide. An implementation may implement wider ranges. Also,
sizeof(long) is allowed to be equal to sizeof(int).
> Does it have
something to do with how the numbers are represented on a particular
machine ?

Um, yes and no.

If you're talking about why INT_MIN is far smaller than the one given in
K&R2 and INT_MAX is far greater than the one given in K&R2, it is more
related to the number of bits used to store an int.

If it's about why INT_MIN for a 32-bit int can be -2147483648 or
-2147483647, then it has something to do with how a signed int is
internally represented in an implementation.

HTH.
 
R

rams

I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:

#include <stdio.h>
#include <limits.h>

int main(void)
{
   printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
  printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);
  return 0;

}

the o/p that i get:
INT_MIN:-2147483648                 INT_MAX: 2147483647
LONG_MIN:-2147483648             LONG_MAX: 2147483647

basically the same thing. why is this happening ? also these ranges
seem to contradict with the one given in K & R 2. Does it have
something to do with how the numbers are represented on a particular
machine ?

hi
i dont know very much about the macros you have used
yes , the range is depeneds on machine
but here is the solution to find range
#include<stdio.h>
#include<math.h>
int main()
{
printf("sizeof signed int %d, sizeof long %l\n",(power(2,
(8*sizeof(int))-1),(power(2,8*sizeof(int))-1) );
retrun 0;

}

probably it will work , do modification for compilation errors
 
S

santosh

pereges said:
I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:


#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);

You probably want to reverse the arguments after the format string, or
correct the string to reflect the order of it's succeeding arguments.
And you want to change the format specifier from %d to %ld.
return 0;
}

the o/p that i get:
INT_MIN:-2147483648 INT_MAX: 2147483647
LONG_MIN:-2147483648 LONG_MAX: 2147483647

basically the same thing. why is this happening ?

Why shouldn't it happen? Int and long are often types of identical range
(and possibly size) on many implementation. All that the standard
requires is that the type int should be able to hold values in the
range -32,767 and 32,767 and that the type long be able to hold the
values in the range -2,147,483,647 and 2,147,483,647 inclusive.
also these ranges
seem to contradict with the one given in K & R 2.

They don't. The values given in K&R2 and the standard are the minimum.
Implementations are allowed to exceed them by any amount, as long as
the next wider type in the hierarchy is able to hold at least the same
range of values as it's predecessor.
Does it have
something to do with how the numbers are represented on a particular
machine ?

Yes. Your machine is likely to be using the ubiquitous twos complement
representation. The C standard however has to make allowances for both
sign-and-magnitude and ones-complement formats; hence the slight
difference between your observed values and the ones in the standard,
at least for long.
 
J

Jens Thoms Toerring

i dont know very much about the macros you have used
yes , the range is depeneds on machine
but here is the solution to find range

No, the solution to find the ranges is using those macros.
Everything else only works by making assumptions that may
or may a well not be correct on a certain machine.
#include<stdio.h>
#include<math.h>
int main()
{
printf("sizeof signed int %d, sizeof long %l\n",(power(2,
(8*sizeof(int))-1),(power(2,8*sizeof(int))-1) );

You make at least two assumptions that may be wrong. First
you assume that a char always has 8 bits. That' not the case
on quite a number of systems and that's why there is the
CHAR_BIT macro which tells you how many bits a char has.
And, second you assume that all available bits are used
in the representation of a number which, while probably
correct in most cases, is nothing you can 100% rely on.

I'm not going to comment on the several bugs you managed
to squeeze into a single line of code, just one really
important thing the compiler probably won't find for you:
if you use "%d" as the format specifier you must have an
int argument at the corresponding position. And the pow()
function (I guess that's what you meant when you wrote
power()) returns a double and not an int.

Regards, Jens
 
K

Keith Thompson

pereges said:
I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:


#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);
return 0;
}

the o/p that i get:
INT_MIN:-2147483648 INT_MAX: 2147483647
LONG_MIN:-2147483648 LONG_MAX: 2147483647

basically the same thing. why is this happening ? also these ranges
seem to contradict with the one given in K & R 2. Does it have
something to do with how the numbers are represented on a particular
machine ?

The output you showed us did not come from the program you showed us.
When you post code here, please copy-and-paste the *exact* program,
and the *exact* output.

In your second printf, you print the string "LONG_MAX" before the
string "LONG_MIN" (but you print the values in the reverse order).
The output shows "LONG_MIN", then "LONG_MAX". Also, the long string
of blanks in the middle of each output line isn't in your format
string.

Also, it's best to print a new-line "\n" at the *end* of each line of
output, not at the beginning. There's no new-line at the very end of
your output; on some systems, that could result in lost or hidden
output, or perhaps something worse.

And you need to use the right format for the type you're printing.

Here's a revised version of your program, with these problems fixed:

#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN : %d INT_MAX : %d\n", INT_MIN, INT_MAX);
printf("LONG_MIN : %ld LONG_MAX : %ld\n", LONG_MIN, LONG_MAX);
return 0;
}

and the actual output:

INT_MIN : -2147483648 INT_MAX : 2147483647
LONG_MIN : -2147483648 LONG_MAX : 2147483647
 
S

santosh

pereges said:
I wrote a small program to check the range for int(signed) and long
int(signed) on my machine:


#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("INT_MIN:%d INT_MAX: %d", INT_MIN, INT_MAX);
printf("\nLONG_MAX: %d LONG_MIN: %d", LONG_MIN, LONG_MAX);
return 0;
}

the o/p that i get:
INT_MIN:-2147483648 INT_MAX: 2147483647
LONG_MIN:-2147483648 LONG_MAX: 2147483647

basically the same thing. why is this happening ? also these ranges
seem to contradict with the one given in K & R 2. Does it have
something to do with how the numbers are represented on a particular
machine ?

Also here is a program I wrote some time ago for printing various limits
of the C translation and execution environment.

/* Program to print various implementation defined numerical limits.
*
* Set C99_CONFORMANCE to one if your compiler supports the features
* needed by this program, but fails to define __STDC_VERSION to
199901L.
* TODO: Include complex and imaginary types and features of the runtime
* floating point environment through <fenv.h>
*/
#define C99_CONFORMANCE 1
#if __STDC_VERSION__ == 199901L || C99_CONFORMANCE == 1
#define HAVE_C99 1
#endif

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include <signal.h>
#include <wchar.h>

#ifdef HAVE_C99
#include <inttypes.h>
#include <stdbool.h>
#endif

int main(void)
{
int dummy;
printf(
"\nCHAR_BIT == %d\n\n"
"Type\t\t\tSize\tMin.\t\t\tMax.\n"
"============================================================\n\n"
#if HAVE_C99 && __bool_true_false_are_defined
"bool\t\t\t%u\n"
#elif HAVE_C99
"_Bool\t\t\t%u\n"
#endif
"char\t\t\t1\t%d\t\t\t%u\n"
"signed char\t\t1\t%d\t\t\t%d\n"
"unsigned char\t\t1\t0\t\t\t%u\n"
"short\t\t\t%u\t%d\t\t\t%d\n"
"unsigned short\t\t%u\t0\t\t\t%u\n"
"int\t\t\t%u\t%d\t\t%d\n"
"unsigned int\t\t%u\t0\t\t\t%u\n"
"long\t\t\t%u\t%ld\t\t%ld\n"
"unsigned long\t\t%u\t0\t\t\t%lu\n",
CHAR_BIT,
#if HAVE_C99 && __bool_true_false_are_defined
(unsigned)sizeof(bool),
#elif HAVE_C99
(unsigned)sizeof(_Bool),
#endif
CHAR_MIN, CHAR_MAX,
SCHAR_MIN, SCHAR_MAX,
UCHAR_MAX,
(unsigned)sizeof(short), SHRT_MIN, SHRT_MAX,
(unsigned)sizeof(unsigned short), USHRT_MAX,
(unsigned)sizeof(int), INT_MIN, INT_MAX,
(unsigned)sizeof(unsigned int), UINT_MAX,
(unsigned)sizeof(long), LONG_MIN, LONG_MAX,
(unsigned)sizeof(unsigned long), ULONG_MAX);
#ifdef HAVE_C99
printf(
"long long\t\t%u\t%lld\t%lld\n"
"unsigned long long\t%u\t0\t\t\t%llu\n",
(unsigned)sizeof(long long), LLONG_MIN, LLONG_MAX,
(unsigned)sizeof(unsigned long long), ULLONG_MAX);
#endif
printf(
"float\t\t\t%u\t%g\t\t%g\n"
"double\t\t\t%u\t%g\t\t%g\n"
"long double\t\t%u\t%Lg\t\t%Lg\n",
(unsigned)sizeof(float), FLT_MIN, FLT_MAX,
(unsigned)sizeof(double), DBL_MIN, DBL_MAX,
(unsigned)sizeof(long double), LDBL_MIN, LDBL_MAX);
printf(
"\nAdditional properties of floating types:\n"
"FLT_RADIX\t\t%d\n"
"FLT_MANT_DIG\t\t%d\n"
"DBL_MANT_DIG\t\t%d\n"
"LDBL_MANT_DIG\t\t%d\n"
#ifdef HAVE_C99
"DECIMAL_DIG\t\t%d\n"
#endif
"FLT_DIG\t\t\t%d\n"
"DBL_DIG\t\t\t%d\n"
"LDBL_DIG\t\t%d\n"
"FLT_MIN_EXP\t\t%d\n"
"FLT_MAX_EXP\t\t%d\n"
"DBL_MIN_EXP\t\t%d\n"
"DBL_MAX_EXP\t\t%d\n"
"LDBL_MIN_EXP\t\t%d\n"
"LDBL_MAX_EXP\t\t%d\n"
"FLT_MIN_10_EXP\t\t%d\n"
"FLT_MAX_10_EXP\t\t%d\n"
"DBL_MIN_10_EXP\t\t%d\n"
"DBL_MAX_10_EXP\t\t%d\n"
"LDBL_MIN_10_EXP\t\t%d\n"
"LDBL_MAX_10_EXP\t\t%d\n"
"FLT_EPSILON\t\t%g\n"
"DBL_EPSILON\t\t%g\n"
"LDBL_EPSILON\t\t%Lg\n",
FLT_RADIX, FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG,
#ifdef HAVE_C99
DECIMAL_DIG,
#endif
FLT_DIG, DBL_DIG, LDBL_DIG, FLT_MIN_EXP, FLT_MAX_EXP,
DBL_MIN_EXP,
DBL_MAX_EXP, LDBL_MIN_EXP, LDBL_MAX_EXP, FLT_MIN_10_EXP,
FLT_MAX_10_EXP, DBL_MIN_10_EXP, DBL_MAX_10_EXP, LDBL_MIN_10_EXP,
LDBL_MAX_10_EXP, FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON);

#ifdef HAVE_C99
printf(
"\nProperties of types defined in stdint.h\n"
#ifdef INT8_MIN
"int8_t\t\t\t%u\t%" PRId8 "\t\t\t%" PRId8 "\n"
"uint8_t\t\t\t%u\t0\t\t\t%" PRIu8 "\n"
#endif
#ifdef INT16_MIN
"int16_t\t\t\t%u\t%" PRId16 "\t\t\t%" PRId16 "\n"
"uint16_t\t\t%u\t0\t\t\t%" PRIu16 "\n"
#endif
#ifdef INT32_MIN
"int32_t\t\t\t%u\t%" PRId32 "\t\t%" PRId32 "\n"
"uint32_t\t\t%u\t0\t\t\t%" PRIu32 "\n"
#endif
#ifdef INT64_MIN
"int64_t\t\t\t%u\t%" PRId64 "\t%" PRId64 "\n"
"uint64_t\t\t%u\t0\t\t\t%" PRIu64 "\n"
#endif
"int_least8_t\t\t%u\t%" PRIdLEAST8 "\t\t\t%" PRIdLEAST8 "\n"
"uint_least8_t\t\t%u\t0\t\t\t%" PRIuLEAST8 "\n"
"int_least16_t\t\t%u\t%" PRIdLEAST16 "\t\t\t%" PRIdLEAST16 "\n"
"uint_least16_t\t\t%u\t0\t\t\t%" PRIuLEAST16 "\n"
"int_least32_t\t\t%u\t%" PRIdLEAST32 "\t\t%" PRIdLEAST32 "\n"
"uint_least32_t\t\t%u\t0\t\t\t%" PRIuLEAST32 "\n"
"int_least64_t\t\t%u\t%" PRIdLEAST64 "\t%" PRIdLEAST64 "\n"
"uint_least64_t\t\t%u\t0\t\t\t%" PRIuLEAST64 "\n"
"int_fast8_t\t\t%u\t%" PRIdFAST8 "\t\t\t%" PRIdFAST8 "\n"
"uint_fast8_t\t\t%u\t0\t\t\t%" PRIuFAST8 "\n"
"int_fast16_t\t\t%u\t%" PRIdFAST16 "\t\t%" PRIdFAST16 "\n"
"uint_fast16_t\t\t%u\t0\t\t\t%" PRIuFAST16 "\n"
"int_fast32_t\t\t%u\t%" PRIdFAST32 "\t\t%" PRIdFAST32 "\n"
"uint_fast32_t\t\t%u\t0\t\t\t%" PRIuFAST32 "\n"
"int_fast64_t\t\t%u\t%" PRIdFAST64 "\t%" PRIdFAST64 "\n"
"uint_fast64_t\t\t%u\t0\t\t\t%" PRIuFAST64 "\n"
"intmax_t\t\t%u\t%" PRIdMAX "\t%" PRIdMAX "\n"
"uintmax_t\t\t%u\t0\t\t\t%" PRIuMAX "\n"
#ifdef INTPTR_MIN
"intptr_t\t\t%u\t%" PRIdPTR "\t\t%" PRIdPTR "\n"
#endif
#ifdef UINTPTR_MAX
"uintptr_t\t\t%u\t0\t\t\t%" PRIuPTR "\n"
#endif
"%n"
,
#ifdef INT8_MIN
(unsigned)sizeof(int8_t), INT8_MIN, INT8_MAX,
(unsigned)sizeof(uint8_t), UINT8_MAX,
#endif
#ifdef INT16_MIN
(unsigned)sizeof(int16_t), INT16_MIN, INT16_MAX,
(unsigned)sizeof(uint16_t), UINT16_MAX,
#endif
#ifdef INT32_MIN
(unsigned)sizeof(int32_t), INT32_MIN, INT32_MAX,
(unsigned)sizeof(uint32_t), UINT32_MAX,
#endif
#ifdef INT64_MIN
(unsigned)sizeof(int64_t), INT64_MIN, INT64_MAX,
(unsigned)sizeof(uint64_t), UINT64_MAX,
#endif
(unsigned)sizeof(int_least8_t), INT_LEAST8_MIN, INT_LEAST8_MAX,
(unsigned)sizeof(uint_least8_t), UINT_LEAST8_MAX,
(unsigned)sizeof(int_least16_t), INT_LEAST16_MIN,
INT_LEAST16_MAX,
(unsigned)sizeof(uint_least16_t), UINT_LEAST16_MAX,
(unsigned)sizeof(int_least32_t), INT_LEAST32_MIN,
INT_LEAST32_MAX,
(unsigned)sizeof(uint_least32_t), UINT_LEAST32_MAX,
(unsigned)sizeof(int_least64_t), INT_LEAST64_MIN,
INT_LEAST64_MAX,
(unsigned)sizeof(uint_least64_t), UINT_LEAST64_MAX,
(unsigned)sizeof(int_fast8_t), INT_FAST8_MIN, INT_FAST8_MAX,
(unsigned)sizeof(uint_fast8_t), UINT_FAST8_MAX,
(unsigned)sizeof(int_fast16_t), INT_FAST16_MIN, INT_FAST16_MAX,
(unsigned)sizeof(uint_fast16_t), UINT_FAST16_MAX,
(unsigned)sizeof(int_fast32_t), INT_FAST32_MIN, INT_FAST32_MAX,
(unsigned)sizeof(uint_fast32_t), UINT_FAST32_MAX,
(unsigned)sizeof(int_fast64_t), INT_FAST64_MIN, INT_FAST64_MAX,
(unsigned)sizeof(uint_fast64_t), UINT_FAST64_MAX,
(unsigned)sizeof(intmax_t), INTMAX_MIN, INTMAX_MAX,
(unsigned)sizeof(uintmax_t), UINTMAX_MAX,
#ifdef INTPTR_MIN
(unsigned)sizeof(intptr_t), INTPTR_MIN, INTPTR_MAX,
#endif
#ifdef UINTPTR_MAX
(unsigned)sizeof(uintptr_t), UINTPTR_MAX,
#endif
&dummy);
#endif

printf(
"\nOther types:\n"
"ptrdiff_t\t\t%u"
#ifdef PTRDIFF_MIN
"\t%td\t\t%td"
#endif
"\n"
"size_t\t\t\t%u\t0\t\t\t%lu\n"
#ifdef WCHAR_MIN
"wchar_t\t\t\t%u\t%ld\t\t%lu\n"
#endif
#ifdef WINT_MIN
"wint_t\t\t\t%u\t%d\t\t\t%u\n"
#endif
"sig_atomic_t\t\t%u"
#ifdef SIG_ATOMIC_MIN
"\t%d\t\t%u"
#endif
"\n"

"BUFSIZ\t\t\t%lu\n"
"FOPEN_MAX\t\t%u\n"
"FILENAME_MAX\t\t%u\n"
"L_tmpnam\t\t%u\n"
"TMP_MAX\t\t\t%lu\n"
"RAND_MAX\t\t%lu\n"
"MB_LEN_MAX\t\t%lu\n"
"MB_CUR_MAX\t\t%lu\n"
"%n",
(unsigned)sizeof(ptrdiff_t),
#ifdef PTRDIFF_MIN
PTRDIFF_MIN, PTRDIFF_MAX,
#endif
(unsigned)sizeof(size_t), (unsigned long)((size_t)-1),
#ifdef WCHAR_MIN
(unsigned)sizeof(wchar_t), WCHAR_MIN, WCHAR_MAX,
#endif
#ifdef WINT_MIN
(unsigned)sizeof(wint_t), WINT_MIN, WINT_MAX,
#endif
(unsigned)sizeof(sig_atomic_t),
#ifdef SIG_ATOMIC_MIN
SIG_ATOMIC_MIN, SIG_ATOMIC_MAX,
#endif
(unsigned long)BUFSIZ, FOPEN_MAX, FILENAME_MAX, L_tmpnam,
(unsigned long)TMP_MAX, (unsigned long)RAND_MAX,
(unsigned long)MB_LEN_MAX, (unsigned long)MB_CUR_MAX, &dummy);

return 0;
}
 

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

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top