/*
 * LIMITS.C - decipher the basic C binary data type limits
 *
 * Source Version: 9.0
 * Software Release #92-0043
 *
 * #include "cpyright.h"
 *
 */

#include <stdio.h>

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* MAIN - start here */

main()
   {int i, nfp, fw;
    char format[40];
    unsigned char cmn, cmx;
    short smn, smx;
    int imn, imx;
    unsigned int uimx;
    long lmn, lmx;
    float fmn, fmx;
    double dmn, dmx, conf;
    union ucsil
          {unsigned char b[32];
           unsigned char c;
           short s;
           int i;
           unsigned int ui;
           long l;
           float f;
           double d;} bo, bp;

    printf("\n");

/* do the char limits */
    cmn = 0;
    cmx  = 0xFF;
    printf("#define CHAR_MIN\t %d\n", cmn);
    printf("#define CHAR_MAX\t %d\n", cmx);

/* do the short limits */
    for (smn = 0x80, i = 1; i < sizeof(short); i++)
        smn <<= 8;
    bo.s = smn;
    for (i = 0; i < sizeof(short); i++)
        bo.b[i] = ~bo.b[i];
    smx = bo.s;

    printf("#define SHRT_MIN\t%d\n", smn);
    printf("#define SHRT_MAX\t %d\n", smx);

/* do the int limits */
    for (imn = 0x80, i = 1; i < sizeof(int); i++)
        imn <<= 8;
    bo.i = imn;
    for (i = 0; i < sizeof(int); i++)
        bo.b[i] = ~bo.b[i];
    imx = bo.i;

    printf("#define INT_MIN \t%d\n", imn);
    printf("#define INT_MAX \t %d\n", imx);

/* do the unsigned int limits */
    for (i = 0; i < sizeof(int); i++)
        {uimx <<= 8;
         uimx |= 0xFF;}
    printf("#define UINT_MAX\t %u\n",  uimx);

/* do the long limits */
    for (lmn = 0x80, i = 1; i < sizeof(long); i++)
        lmn <<= 8;
    bo.l = lmn;
    for (i = 0; i < sizeof(long); i++)
        bo.b[i] = ~bo.b[i];
    lmx = bo.l;

    printf("#define LONG_MIN\t%ld\n", lmn);
    printf("#define LONG_MAX\t %ld\n", lmx);

    conf = 24.0/10.0;

/* the floating point algorithm will not work as is for CRAY arithmetic
 * no big deal since they have an ANSI compiler which will have the
 * necessary constants
 * GOTCHA: this is also not guaranteed as is to work with formats using
 * the mantissa guard bit (IEEE 96 bit format for example)
 */

/* do the float limits */
    bo.f = 1.0;
    bp.f = 0.5;
    for (i = 0; i < sizeof(float); i++)
        {bo.b[i] = bo.b[i] & (~bp.b[i]);
         bp.b[i] = 0xFF ^ bo.b[i];};
    fmn =  bo.f;
    fmx = -bp.f;

    nfp  = conf*(sizeof(float) - 1.0) + 1;
    fw   = nfp + 8;
    sprintf(format, "%%s%%%d.%de", fw, nfp);

    printf(format, "#define FLT_MIN \t", fmn);
    printf("\n");

    printf(format, "#define FLT_MAX \t", fmx);
    printf("\n");

/* do the double limits */
    bo.d = 1.0;
    bp.d = 0.5;
    for (i = 0; i < sizeof(double); i++)
        {bo.b[i] = bo.b[i] & (~bp.b[i]);
         bp.b[i] = 0xFF ^ bo.b[i];};
    dmn =  bo.d;
    dmx = -bp.d;

    nfp  = conf*(sizeof(double) - 1.0) + 1;
    fw   = nfp + 8;
    sprintf(format, "%%s%%%d.%de", fw, nfp);

    printf(format, "#define DBL_MIN \t", dmn);
    printf("\n");

    printf(format, "#define DBL_MAX \t", dmx);
    printf("\n\n");

    return(0);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

