Direct computation of integer limits in K&R2?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • santosh

    Direct computation of integer limits in K&R2?

    Hello all,

    In K&R2 one exercise asks the reader to compute and print the limits for
    the basic integer types. This is trivial for unsigned types. But is it
    possible for signed types without invoking undefined behaviour
    triggered by overflow? Remember that the constants in limits.h cannot
    be used.

  • Ian Collins

    #2
    Re: Direct computation of integer limits in K&R2?

    santosh wrote:
    Hello all,
    >
    In K&R2 one exercise asks the reader to compute and print the limits for
    the basic integer types. This is trivial for unsigned types. But is it
    possible for signed types without invoking undefined behaviour
    triggered by overflow? Remember that the constants in limits.h cannot
    be used.
    >
    Isn't it possible to calculate this based on the unsigned types of the
    same size?

    --
    Ian Collins.

    Comment

    • santosh

      #3
      Re: Direct computation of integer limits in K&R2?

      Ian Collins wrote:
      santosh wrote:
      >Hello all,
      >>
      >In K&R2 one exercise asks the reader to compute and print the limits
      >for the basic integer types. This is trivial for unsigned types. But
      >is it possible for signed types without invoking undefined behaviour
      >triggered by overflow? Remember that the constants in limits.h cannot
      >be used.
      >>
      Isn't it possible to calculate this based on the unsigned types of the
      same size?
      Won't this require knowledge of the encoding used, whether twos
      complement or sign and magnitude etc?

      Comment

      • Harald van =?UTF-8?b?RMSzaw==?=

        #4
        Re: Direct computation of integer limits in K&R2?

        On Wed, 12 Mar 2008 03:07:48 +0530, santosh wrote:
        Hello all,
        >
        In K&R2 one exercise asks the reader to compute and print the limits for
        the basic integer types. This is trivial for unsigned types. But is it
        possible for signed types without invoking undefined behaviour triggered
        by overflow? Remember that the constants in limits.h cannot be used.
        #include <stdio.h>
        int main(void) {
        unsigned u = -1;
        int i;
        while ((i = u) < 0 || i != u)
        u = u >1;
        printf("INT_MAX == %u\n", u);
        }

        This is not guaranteed to work in C99, where the conversion of an out-of-
        range integer may raise a signal, but it's valid C90, since the result of
        the conversion must be a valid int, and therefore between INT_MIN and
        INT_MAX.

        Comment

        • Ian Collins

          #5
          Re: Direct computation of integer limits in K&amp;R2?

          santosh wrote:
          Ian Collins wrote:
          >
          >santosh wrote:
          >>Hello all,
          >>>
          >>In K&R2 one exercise asks the reader to compute and print the limits
          >>for the basic integer types. This is trivial for unsigned types. But
          >>is it possible for signed types without invoking undefined behaviour
          >>triggered by overflow? Remember that the constants in limits.h cannot
          >>be used.
          >>>
          >Isn't it possible to calculate this based on the unsigned types of the
          >same size?
          >
          Won't this require knowledge of the encoding used, whether twos
          complement or sign and magnitude etc?
          >
          I think so, I should have added that.

          --
          Ian Collins.

          Comment

          • Peter Nilsson

            #6
            Re: Direct computation of integer limits in K&amp;R2?

            santosh <santosh....@gm ail.comwrote:
            In K&R2 one exercise asks the reader to compute and
            print the limits for the basic integer types. This is
            trivial for unsigned types. But is it possible for
            signed types without invoking undefined behaviour
            triggered by overflow? Remember that the constants
            in limits.h cannot be used.
            Yes. Unlike C99, unsigned to signed integer conversion
            is implementation defined without the possibility of
            raising a signal. So...

            <http://groups.google.c om/group/comp.lang.c/msg/ffe17c645660b76 c>

            INT_MIN isn't computed per se, rather it's derived by
            determining the representation for negative ints. [I
            know pete posted some very simple constant expressions,
            though it was some time ago.]

            --
            Peter

            Comment

            • santosh

              #7
              Re: Direct computation of integer limits in K&amp;R2?

              Harald van D?k wrote:
              On Wed, 12 Mar 2008 03:07:48 +0530, santosh wrote:
              >Hello all,
              >>
              >In K&R2 one exercise asks the reader to compute and print the limits
              >for the basic integer types. This is trivial for unsigned types. But
              >is it possible for signed types without invoking undefined behaviour
              >triggered by overflow? Remember that the constants in limits.h cannot
              >be used.
              >
              #include <stdio.h>
              int main(void) {
              unsigned u = -1;
              int i;
              while ((i = u) < 0 || i != u)
              u = u >1;
              printf("INT_MAX == %u\n", u);
              }
              >
              This is not guaranteed to work in C99, where the conversion of an
              out-of- range integer may raise a signal, but it's valid C90, since
              the result of the conversion must be a valid int, and therefore
              between INT_MIN and INT_MAX.
              Thanks. What about the minima?

              Comment

              • santosh

                #8
                Re: Direct computation of integer limits in K&amp;R2?

                Peter Nilsson wrote:
                santosh <santosh....@gm ail.comwrote:
                >In K&R2 one exercise asks the reader to compute and
                >print the limits for the basic integer types. This is
                >trivial for unsigned types. But is it possible for
                >signed types without invoking undefined behaviour
                >triggered by overflow? Remember that the constants
                >in limits.h cannot be used.
                >
                Yes. Unlike C99, unsigned to signed integer conversion
                is implementation defined without the possibility of
                raising a signal. So...
                >
                <http://groups.google.c om/group/comp.lang.c/msg/ffe17c645660b76 c>
                >
                INT_MIN isn't computed per se, rather it's derived by
                determining the representation for negative ints. [I
                know pete posted some very simple constant expressions,
                though it was some time ago.]
                Would you say that this exercise is overly complex for that point in
                K&R2?

                Comment

                • Harald van =?UTF-8?b?RMSzaw==?=

                  #9
                  Re: Direct computation of integer limits in K&amp;R2?

                  On Wed, 12 Mar 2008 03:29:53 +0530, santosh wrote:
                  Harald van D?k wrote:
                  >On Wed, 12 Mar 2008 03:07:48 +0530, santosh wrote:
                  >>Hello all,
                  >>>
                  >>In K&R2 one exercise asks the reader to compute and print the limits
                  >>for the basic integer types. This is trivial for unsigned types. But
                  >>is it possible for signed types without invoking undefined behaviour
                  >>triggered by overflow? Remember that the constants in limits.h cannot
                  >>be used.
                  >>
                  >#include <stdio.h>
                  >int main(void) {
                  > unsigned u = -1;
                  > int i;
                  > while ((i = u) < 0 || i != u)
                  > u = u >1;
                  > printf("INT_MAX == %u\n", u);
                  >}
                  >>
                  >This is not guaranteed to work in C99, where the conversion of an
                  >out-of- range integer may raise a signal, but it's valid C90, since the
                  >result of the conversion must be a valid int, and therefore between
                  >INT_MIN and INT_MAX.
                  >
                  Thanks. What about the minima?
                  Up to INT_MIN, you can use this same idea, except start from LONG_MIN
                  instead of UINT_MAX. For LONG_MIN, I would cheat with
                  strtol("-999999999", 0, 0)
                  adding 9s until a range error is returned. :-)

                  Comment

                  • santosh

                    #10
                    Re: Direct computation of integer limits in K&amp;R2?

                    Harald van D?k wrote:
                    On Wed, 12 Mar 2008 03:29:53 +0530, santosh wrote:
                    >Harald van D?k wrote:
                    >>On Wed, 12 Mar 2008 03:07:48 +0530, santosh wrote:
                    >>>Hello all,
                    >>>>
                    >>>In K&R2 one exercise asks the reader to compute and print the
                    >>>limits for the basic integer types. This is trivial for unsigned
                    >>>types. But is it possible for signed types without invoking
                    >>>undefined behaviour triggered by overflow? Remember that the
                    >>>constants in limits.h cannot be used.
                    >>>
                    >>#include <stdio.h>
                    >>int main(void) {
                    >> unsigned u = -1;
                    >> int i;
                    >> while ((i = u) < 0 || i != u)
                    >> u = u >1;
                    >> printf("INT_MAX == %u\n", u);
                    >>}
                    >>>
                    >>This is not guaranteed to work in C99, where the conversion of an
                    >>out-of- range integer may raise a signal, but it's valid C90, since
                    >>the result of the conversion must be a valid int, and therefore
                    >>between INT_MIN and INT_MAX.
                    >>
                    >Thanks. What about the minima?
                    >
                    Up to INT_MIN, you can use this same idea, except start from LONG_MIN
                    instead of UINT_MAX. For LONG_MIN, I would cheat with
                    strtol("-999999999", 0, 0)
                    adding 9s until a range error is returned. :-)
                    Okay. I for one am glad that limits.h exists. :-)

                    Comment

                    • Flash Gordon

                      #11
                      Re: Direct computation of integer limits in K&amp;R2?

                      Ian Collins wrote, On 11/03/08 21:54:
                      santosh wrote:
                      >Ian Collins wrote:
                      >>
                      >>santosh wrote:
                      >>>Hello all,
                      >>>>
                      >>>In K&R2 one exercise asks the reader to compute and print the limits
                      >>>for the basic integer types. This is trivial for unsigned types. But
                      >>>is it possible for signed types without invoking undefined behaviour
                      >>>triggered by overflow? Remember that the constants in limits.h cannot
                      >>>be used.
                      >>>>
                      >>Isn't it possible to calculate this based on the unsigned types of the
                      >>same size?
                      >Won't this require knowledge of the encoding used, whether twos
                      >complement or sign and magnitude etc?
                      >>
                      I think so, I should have added that.
                      Even if you know it is 2s complement you still can't do it. You need to
                      know whether sign bit = 1 and all value bits = 0 is a trap or not since
                      it is allowed to be a trap representation.
                      --
                      Flash Gordon

                      Comment

                      • Micah Cowan

                        #12
                        Re: Direct computation of integer limits in K&amp;R2?

                        Flash Gordon <spam@flash-gordon.me.ukwri tes:
                        Ian Collins wrote, On 11/03/08 21:54:
                        >santosh wrote:
                        >>Ian Collins wrote:
                        >>>
                        >>>santosh wrote:
                        >>>>Hello all,
                        >>>>>
                        >>>>In K&R2 one exercise asks the reader to compute and print the limits
                        >>>>for the basic integer types. This is trivial for unsigned types. But
                        >>>>is it possible for signed types without invoking undefined behaviour
                        >>>>triggered by overflow? Remember that the constants in limits.h cannot
                        >>>>be used.
                        >>>>>
                        >>>Isn't it possible to calculate this based on the unsigned types of the
                        >>>same size?
                        >>Won't this require knowledge of the encoding used, whether twos
                        >>complement or sign and magnitude etc?
                        >>>
                        >I think so, I should have added that.
                        >
                        Even if you know it is 2s complement you still can't do it. You need
                        to know whether sign bit = 1 and all value bits = 0 is a trap or not
                        since it is allowed to be a trap representation.
                        It's only allowed to be a trap representation on _non_ two's
                        complement representations . sign bit = 1 and all value bits = 0 (and
                        padding bits at non-trap values) would necessarily be the minimum
                        representable value.

                        --
                        Micah J. Cowan
                        Programmer, musician, typesetting enthusiast, gamer...

                        Comment

                        • user923005

                          #13
                          Re: Direct computation of integer limits in K&amp;R2?

                          On Mar 11, 2:37 pm, santosh <santosh....@gm ail.comwrote:
                          Hello all,
                          >
                          In K&R2 one exercise asks the reader to compute and print the limits for
                          the basic integer types. This is trivial for unsigned types. But is it
                          possible for signed types without invoking undefined behaviour
                          triggered by overflow? Remember that the constants in limits.h cannot
                          be used.
                          /*
                          The standard hearder <limits.hwas introduced on the same page (36)
                          as the exercise.
                          We are told to compute the values by standard headers and by direct
                          computation.
                          We are also told to determine the ranges of the various floating point
                          types.

                          The only hard part I see is the signed integer min and max values
                          without using <limits.hbecaus e I do not see how you can do it
                          portably. We can probably deduce the hardware type, but I am not sure
                          about what guarantees we have as to internal representation. I guess
                          also we will need separate routines for 2's complement, 1's
                          complement, sign magnitude, and whatever other types are allowed (e.g.
                          is decimal storage allowed? I know of CPUs that had BCD instructions
                          in hardware).

                          Anyway, here are all the trivial answers:

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

                          void floating_limits (void)
                          {
                          puts("\nFloatin g point limits:");
                          printf("DBL_DIG %u\n", (unsigned) DBL_DIG);
                          printf("DBL_EPS ILON %*.*g\n", DBL_DIG + 3, DBL_DIG,
                          DBL_EPSILON);
                          printf("DBL_MAN T_DIG %u\n", (unsigned) DBL_MANT_DIG);
                          printf("DBL_MAX %*.*g\n", DBL_DIG + 3, DBL_DIG, DBL_MAX);
                          printf("DBL_MAX _10_EXP %u\n", (unsigned) DBL_MAX_10_EXP) ;
                          printf("DBL_MAX _EXP %u\n", (unsigned) DBL_MAX_EXP);
                          printf("DBL_MIN %*.*g\n", DBL_DIG + 3, DBL_DIG, DBL_MIN);
                          printf("DBL_MIN _10_EXP %d\n", DBL_MIN_10_EXP) ;
                          printf("DBL_MIN _EXP %d\n", DBL_MIN_EXP);
                          #ifdef DBL_RADIX
                          printf("DBL_RAD IX %u\n", (unsigned) DBL_RADIX);
                          #endif
                          #ifdef DBL_ROUNDS
                          printf("DBL_ROU NDS %u\n", (unsigned) DBL_ROUNDS);
                          #endif
                          printf("FLT_DIG %u\n", (unsigned) FLT_DIG);
                          printf("FLT_EPS ILON %*.*g\n", FLT_DIG + 3, FLT_DIG,
                          FLT_EPSILON);
                          #ifdef FLT_GUARD
                          printf("FLT_GUA RD %u\n", (unsigned) FLT_GUARD);
                          #endif
                          printf("FLT_MAN T_DIG %u\n", (unsigned) FLT_MANT_DIG);
                          printf("FLT_MAX %*.*g\n", FLT_DIG + 3, FLT_DIG, FLT_MAX);
                          printf("FLT_MAX _10_EXP %u\n", (unsigned) FLT_MAX_10_EXP) ;
                          printf("FLT_MAX _EXP %u\n", (unsigned) FLT_MAX_EXP);
                          printf("FLT_MIN %*.*g\n", FLT_DIG + 3, FLT_DIG, FLT_MIN);
                          printf("FLT_MIN _10_EXP %d\n", FLT_MIN_10_EXP) ;
                          printf("FLT_MIN _EXP %d\n", FLT_MIN_EXP);
                          printf("LDBL_DI G %u\n", (unsigned) LDBL_DIG);
                          printf("LDBL_EP SILON %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
                          double) LDBL_EPSILON);
                          printf("LDBL_MA NT_DIG %u\n", (unsigned) LDBL_MANT_DIG);
                          printf("LDBL_MA X %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
                          double) LDBL_MAX);
                          printf("LDBL_MA X_10_EXP %u\n", (unsigned) LDBL_MAX_10_EXP );
                          printf("LDBL_MA X_EXP %u\n", (unsigned) LDBL_MAX_EXP);
                          printf("LDBL_MI N %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
                          double) LDBL_MIN);
                          printf("LDBL_MI N_10_EXP %d\n", LDBL_MIN_10_EXP );
                          printf("LDBL_MI N_EXP %d\n", LDBL_MIN_EXP);
                          #ifdef LDBL_RADIX
                          printf("LDBL_RA DIX %u\n", (unsigned) LDBL_RADIX);
                          #endif
                          #ifdef LDBL_ROUNDS
                          printf("LDBL_RO UNDS %u\n", (unsigned) LDBL_ROUNDS);
                          #endif
                          }

                          void signed_limits_g uarantee(void)
                          {
                          static const short shrt_min_est = -32767;
                          static const short shrt_max_est = +32767;
                          static const int int_min_est = -32767;
                          static const int int_max_est = +32767;
                          static const long long_min_est = -2147483647L;
                          static const long long_max_est = +2147483647L;
                          static const long long llong_min_est = -922337203685477 5807LL;
                          static const long long llong_max_est = +92233720368547 75807LL;
                          puts("\nSigned limits guaranteed by the standard to be at
                          least:");
                          printf("Signed short min %d\n", shrt_min_est);
                          printf("Signed short max %d\n", shrt_max_est);
                          printf("Signed int min %d\n", int_min_est);
                          printf("Signed int max %d\n", int_max_est);
                          printf("Signed long min %ld\n", long_min_est);
                          printf("Signed long max %ld\n", long_max_est);
                          printf("Signed long long min %lld\n", llong_min_est);
                          printf("Signed long long max %lld\n", llong_max_est);

                          }

                          void limits_lookup(v oid)
                          {
                          puts("\nLookup from limits.h:");
                          printf("Width of Char %d\n", CHAR_BIT);
                          printf("Signed Char max %d\n", CHAR_MAX);
                          printf("Signed Char min %d\n", CHAR_MIN);
                          printf("Unsigne d Char max %d\n", UCHAR_MAX);
                          printf("Signed short min %d\n", SHRT_MIN);
                          printf("Signed short max %d\n", SHRT_MAX);
                          printf("Unsigne d short max %u\n", USHRT_MAX);
                          printf("Signed int min %d\n", INT_MIN);
                          printf("Signed int max %d\n", INT_MAX);
                          printf("Unsigne d int max %u\n", UINT_MAX);
                          printf("Signed long min %ld\n", LONG_MIN);
                          printf("Signed long max %ld\n", LONG_MAX);
                          printf("Unsigne d long max %lu\n", ULONG_MAX);
                          printf("Signed long long min %lld\n", LLONG_MIN);
                          printf("Signed long long max %lld\n", LLONG_MAX);
                          printf("Unsigne d long long max %llu\n", ULLONG_MAX);
                          }

                          void compute_unsigne d_max(void)
                          {
                          unsigned long long ullm = -1;
                          unsigned um = -1;
                          unsigned long ulm = -1;
                          unsigned short usm = -1;
                          unsigned char ucm = -1;
                          puts("\nSimple computation of unsigned maximums:");
                          printf("Unsigne d Char max %d\n", ucm);
                          printf("Unsigne d short max %u\n", usm);
                          printf("Unsigne d int max %u\n", um);
                          printf("Unsigne d long max %lu\n", ulm);
                          printf("Unsigne d long long max %llu\n", ullm);
                          }

                          int main(void)
                          {
                          limits_lookup() ;
                          compute_unsigne d_max();
                          signed_limits_g uarantee();
                          floating_limits ();
                          return 0;
                          }

                          Comment

                          • user923005

                            #14
                            Re: Direct computation of integer limits in K&amp;R2?

                            On Mar 11, 2:54 pm, Harald van D©¦k <true...@gmail. comwrote:
                            On Wed, 12 Mar 2008 03:07:48 +0530, santosh wrote:
                            Hello all,
                            >
                            In K&R2 one exercise asks the reader to compute and print the limits for
                            the basic integer types. This is trivial for unsigned types. But is it
                            possible for signed types without invoking undefined behaviour triggered
                            by overflow? Remember that the constants in limits.h cannot be used.
                            >
                            #include <stdio.h>
                            int main(void) {
                            unsigned u = -1;
                            int i;
                            while ((i = u) < 0 || i != u)
                            u = u >1;
                            printf("INT_MAX == %u\n", u);
                            >
                            }
                            >
                            This is not guaranteed to work in C99, where the conversion of an out-of-
                            range integer may raise a signal, but it's valid C90, since the result of
                            the conversion must be a valid int, and therefore between INT_MIN and
                            INT_MAX.
                            What happens if INT_MAX is larger than UINT_MAX? I see no guarantees
                            that this is not possible.

                            Comment

                            • muntyan@gmail.com

                              #15
                              Re: Direct computation of integer limits in K&amp;R2?

                              On Mar 11, 7:30 pm, Micah Cowan <mi...@cowan.na mewrote:
                              Flash Gordon <s...@flash-gordon.me.ukwri tes:
                              Ian Collins wrote, On 11/03/08 21:54:
                              santosh wrote:
                              >Ian Collins wrote:
                              >
                              >>santosh wrote:
                              >>>Hello all,
                              >
                              >>>In K&R2 one exercise asks the reader to compute and print the limits
                              >>>for the basic integer types. This is trivial for unsigned types. But
                              >>>is it possible for signed types without invoking undefined behaviour
                              >>>triggered by overflow? Remember that the constants in limits.h cannot
                              >>>be used.
                              >
                              >>Isn't it possible to calculate this based on the unsigned types of the
                              >>same size?
                              >Won't this require knowledge of the encoding used, whether twos
                              >complement or sign and magnitude etc?
                              >
                              I think so, I should have added that.
                              >
                              Even if you know it is 2s complement you still can't do it. You need
                              to know whether sign bit = 1 and all value bits = 0 is a trap or not
                              since it is allowed to be a trap representation.
                              >
                              It's only allowed to be a trap representation on _non_ two's
                              complement representations . sign bit = 1 and all value bits = 0 (and
                              padding bits at non-trap values) would necessarily be the minimum
                              representable value.
                              6.5.6.2p2 says ("the first two" below are sign-and-magnitude and
                              two's complement):

                              "Which of these applies is implementation-defined, as is whether the
                              value with sign bit 1 and all value bits zero (for the first two),
                              or with sign bit and all value bits 1 (for ones' complement), is a
                              trap representation or a normal value."

                              Comment

                              Working...