title: How to determine the ranges of floating-point types using direct computation?
body: <p>I'm trying to solve exercise 2-1 from "The C Programming Language", 2nd edition, which asks to:</p>
  
  <p>"Write a program to determine the ranges of char, short, int, and long variables, both signed and unsigned, by printing appropriate values from standard headers and by direct computation. Harder if you compute them: determine the ranges of the various floating-point types."</p>
  
  <p>I've managed to determine the ranges of all types except floating-points, both by using minimum and maximum values from standard headers and by direct computation.</p>
  
  <p>How do I determine the ranges of floating-point types using direct computation?</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;limits.h&gt;
  #include &lt;float.h&gt;
  
  #define TESTBIT 2
  
  /* write a program to determine the ranges of char, short, int, and long variables,
     both signed and unsigned by printing appropriate values from standard headers
     and by direct computation
  
     harder if you compute them - determine the ranges of the various floating-point types */
  main()
  {
      char ch, chtest;
      unsigned char uch;
      short sh, shtest;
      unsigned short ush;
      int i, itest;
      unsigned int ui;
      long l, ltest;
      unsigned long ul;
      long long ll, lltest;
      unsigned long long ull;
  
      ch = uch = sh = ush = i = ui = l = ul = ll = ull = 0;
      ++ch;        /* Maximum and minimum ranges using direct computation */
      chtest = 0;
      while (chtest &gt;= 0) {
          chtest = ch * TESTBIT;
          if (chtest &gt; 0)
              ch = ch * TESTBIT;
      }
      ch = ch * 2;
      printf("Minimum range of signed char variable: %d\n", ch);
  
      --ch;
      printf("Maximum range of signed char variable: %d\n", ch);
  
      --uch;
      printf("Maximum range of unsigned char variable: %u\n", uch);
  
      ++sh;
      shtest = 0;
      while (shtest &gt;= 0) {
          shtest = sh * TESTBIT;
          if (shtest &gt; 0)
              sh = sh * TESTBIT;
      }
      sh = sh * 2;
      printf("Minimum range of signed short variable: %d\n", sh);
  
      --sh;
      printf("Maximum range of signed short variable: %d\n", sh);
  
      --ush;
      printf("Maximum range of unsigned short variable: %u\n", ush);
  
      ++i;
      itest = 0;
      while (itest &gt;= 0) {
          itest = i * TESTBIT;
          if (itest &gt; 0)
              i = i * TESTBIT;
      }
      i = i * 2;
      printf("Minimum range of signed int variable: %d\n", i);
  
      --i;
      printf("Maximum range of signed int variable: %d\n", i);
  
      --ui;
      printf("Maximum range of unsigned int variable: %u\n", ui);
  
      ++l;
      ltest = 0;
      while (ltest &gt;= 0) {
          ltest = l * TESTBIT;
          if (ltest &gt; 0)
              l = l * TESTBIT;
      }
      l = l * 2;
      printf("Minimum range of signed long variable: %d\n", l);
  
      --l;
      printf("Maximum range of signed long variable: %d\n", l);
  
      --ul;
      printf("Maximum range of unsigned long variable: %lu\n", ul);
  
      ++ll;
      lltest = 0;
      while (lltest &gt;= 0) {
          lltest = ll * TESTBIT;
          if (lltest &gt; 0)
              ll = ll * TESTBIT;
      }
      ll = ll * 2;
      printf("Minimum range of signed long long variable: %lld\n", ll);
  
      --ll;
      printf("Maximum range of signed long long variable: %lld\n", ll);
  
      --ull;
      printf("Maximum range of unsigned long long variable: %llu\n", ull);
  
      printf("\nSize of char: %d\n", CHAR_BIT);    /* Max and min ranges using limits.h and float.h header */
      printf("Minimum range of signed char variable: %d\n", SCHAR_MIN);
      printf("Maximum range of signed char variable: %d\n", SCHAR_MAX);
      printf("Maximum range of unsigned char variable: %u\n", UCHAR_MAX);
      printf("Minimum range of signed short variable: %d\n", SHRT_MIN);
      printf("Maximum range of signed short variable: %d\n", SHRT_MAX);
      printf("Maximum range of unsigned short variable: %u\n", USHRT_MAX);
      printf("Minimum range of int variable: %d\n", INT_MIN);
      printf("Maximum range of int variable: %d\n", INT_MAX);
      printf("Maximum range of unsigned int variable: %u\n", UINT_MAX);
      printf("Minimum range of signed long variable: %ld\n", LONG_MIN);
      printf("Maximum range of signed long variable: %ld\n", LONG_MAX);
      printf("Maximum range of unsigned long variable: %lu\n", ULONG_MAX);
      printf("Minimum range of long long variable: %lld\n", LLONG_MIN);
      printf("Maximum range of long long variable: %lld\n", LLONG_MAX);
      printf("Maximum range of unsigned long long variable: %llu\n\n", ULONG_LONG_MAX);
      printf("Minimum range of float variable: %f\n", FLT_MIN);
      printf("Maximum range of float variable: %f\n", FLT_MAX);
      printf("Minimum range of double variable: %f\n", DBL_MIN);
      printf("Maximum range of double variable: %f\n", DBL_MAX);
      printf("Minimum range of long double variable: %lf\n", LDBL_MIN);
      printf("Maximum range of long double variable: %lf\n", LDBL_MAX);
      return 0;
  }
  </code></pre>