/**************************************************************************
 *{@C
 *      Copyright:      1988-2024 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UT_Const.h
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    Machine independent constant definitions.
 *
 *      Additional documentation:
 *                      None.
 *
 **************************************************************************/

#ifndef __UT_CONST_H__
#define __UT_CONST_H__

#include "UT_Compat.h"

/*
    MinFloat32          The smallest (normalized or denormalized)
                        Float32 value greater than zero
    MinNrmFloat32       The smallest normalized Float32 value greater than zero
    MaxFloat32          The largest possible Float32 value

    MinFloat64          The smallest (normalized or denormalized)
                        Float64 value greater than zero
    MinNrmFloat64       The smallest normalized Float64 value greater than zero
    MaxFloat64          The largest possible Float64 value

    Float32Prec         Precision of Float32 numbers
    Float64Prec         Precision of Float64 numbers

    MaxUInt64           The largest  possible UInt64 value  (64 bit)
    MaxInt64            The largest  possible Int64  value  (64 bit)
    MinInt64            The smallest possible Int64  value  (64 bit)

    MaxUInt32           The largest  possible UInt32 value  (32 bit)
    MaxInt32            The largest  possible Int32  value  (32 bit)
    MinInt32            The smallest possible Int32  value  (32 bit)

    MaxUInt16           The largest  possible UInt16 value  (16 bit)
    MaxInt16            The largest  possible Int16  value  (16 bit)
    MinInt16            The smallest possible Int16  value  (16 bit)

    MaxUInt8            The largest  possible UInt8  value   ( 8 bit)
    MaxInt8             The largest  possible Int8   value   ( 8 bit)
    MinInt8             The smallest possible Int8   value   ( 8 bit)

    The assertion for normalized numbers is:
    1.0f + MinNrmFloat32 != 1.0f
    1.0  + MinNrmFloat64 != 1.0

    The "Precision" of a Float32 or Float64 number is:
    1.0 / (numeric value of least significant bit in mantissa).
*/

#if defined (USE_PLATFORM_CONST)

    #if defined (Linux)

        #include <float.h>

        #define PLAT_MINFLOAT   FLT_MIN
        #define PLAT_MAXFLOAT   FLT_MAX
        #define PLAT_MINDOUBLE  DBL_MIN
        #define PLAT_MAXDOUBLE  DBL_MAX
        #define PLAT_FSIGNIF    FLT_MANT_DIG
        #define PLAT_DSIGNIF    DBL_MANT_DIG
        #define PLAT_FLOATPREC  FLT_EPSILON
        #define PLAT_DOUBLEPREC DBL_EPSILON

    #elif defined (Darwin)

        #include <float.h>

        #define PLAT_MINFLOAT   FLT_MIN
        #define PLAT_MAXFLOAT   FLT_MAX
        #define PLAT_MINDOUBLE  DBL_MIN
        #define PLAT_MAXDOUBLE  DBL_MAX
        #define PLAT_FSIGNIF    FLT_MANT_DIG
        #define PLAT_DSIGNIF    DBL_MANT_DIG
        #define PLAT_FLOATPREC  FLT_EPSILON
        #define PLAT_DOUBLEPREC DBL_EPSILON

    #elif defined (CC_IS_MSC)

        #include <float.h>

        #define PLAT_MINFLOAT   FLT_MIN
        #define PLAT_MAXFLOAT   FLT_MAX
        #define PLAT_MINDOUBLE  DBL_MIN
        #define PLAT_MAXDOUBLE  DBL_MAX
        #define PLAT_FSIGNIF    FLT_MANT_DIG
        #define PLAT_DSIGNIF    DBL_MANT_DIG
        #define PLAT_FLOATPREC  FLT_EPSILON
        #define PLAT_DOUBLEPREC DBL_EPSILON

    #elif defined (mingw)

        /* Cygwin and MSYS don't define the needed values for floating point
         * numbers. We take the values from Visual C++ 6.0 file "float.h".
         */

        #define PLAT_MINFLOAT   1.175494351e-38F
        #define PLAT_MAXFLOAT   3.402823466e+38F
        #define PLAT_MINDOUBLE  2.2250738585072014e-308
        #define PLAT_MAXDOUBLE  1.7976931348623158e+308
        #define PLAT_FSIGNIF    24
        #define PLAT_DSIGNIF    53
        #define PLAT_FLOATPREC  1.192092896e-07F
        #define PLAT_DOUBLEPREC 2.2204460492503131e-016

    #else

        #error "Definition of MINFLOAT, MAXFLOAT etc. missing here"

    #endif

    #define PO_MINFLOAT         PLAT_MINFLOAT
    #define PO_MAXFLOAT         PLAT_MAXFLOAT
    #define PO_MINDOUBLE        PLAT_MINDOUBLE
    #define PO_MAXDOUBLE        PLAT_MAXDOUBLE
    #define PO_FSIGNIF          PLAT_FSIGNIF
    #define PO_DSIGNIF          PLAT_DSIGNIF
    #define PO_FLOATPREC        PLAT_FLOATPREC
    #define PO_DOUBLEPREC       PLAT_DOUBLEPREC

#else

    /* These numbers have been determined to fit the needs of all
     * supported machine and compiler versions.
     * The defines for the minimum values
     * PO_MINFLOAT, PO_MINDOUBLE, PO_FLOATPREC, PO_DOUBLEPREC
     * must be the biggest value of all supported platforms.
     * The defines for the maximum values 
     * PO_MAXFLOAT, PO_MAXDOUBLE, PO_FSIGNIF, PO_DSIGNIF
     * must be the lowest value of all supported platforms.
     *
     * If adding a new platform, add a new entry above. Then compile and
     * execute UT_ConstTest to check, if the platform specific values fit
     * in the range supplied by the numbers below.
     */

    #define PO_MINFLOAT         1.175494351e-38F
    #define PO_MAXFLOAT         3.402823466e+38F
    #define PO_MINDOUBLE        2.2250738585072014e-308
    #define PO_MAXDOUBLE        1.7976931348623157e+308
    #define PO_FSIGNIF          24
    #define PO_DSIGNIF          53
    #define PO_FLOATPREC        1.19209290e-07F
    #define PO_DOUBLEPREC       2.2204460492503131e-016

#endif /* USE_PLATFORM_CONST */

#define MinFloat32      PO_MINFLOAT
#define MaxFloat32      PO_MAXFLOAT
#define Float32Prec     PO_FLOATPREC

#define MinFloat64      PO_MINDOUBLE
#define MaxFloat64      PO_MAXDOUBLE
#define Float64Prec     PO_DOUBLEPREC

#define MinNrmFloat32   (MinFloat32 * (1.0F / Float32Prec))
#define MinNrmFloat64   (MinFloat64 * (1.0  / Float64Prec))

#define Float32MantLen  PO_FSIGNIF
#define Float64MantLen  PO_DSIGNIF

#define MaxUInt64 ((UInt64)18446744073709551615)
#define MaxInt64  ((Int64) 9223372036854775807)
#define MinInt64  ((Int64) (-MaxInt64-1))

#define MaxUInt32 ((UInt32)4294967295)
#define MaxInt32  ((Int32) 2147483647)
#define MinInt32  ((Int32)(-MaxInt32-1))

#define MaxUInt16 ((UInt16)65535)
#define MaxInt16  ((Int16) 32767)
#define MinInt16  ((Int16)(-MaxInt16-1))

#define MaxUInt8 ((UInt8)255)
#define MaxInt8  ((Int8) 127)
#define MinInt8  ((Int8)(-MaxInt8-1))

#define UT_PI 3.14159265358979323846264338327950
#define UT_PI2 (3.14159265358979323846264338327950 / 2.0)
#define UT_2PI (3.14159265358979323846264338327950 * 2.0)

#endif /* __UT_CONST_H__ */
