/*****************************************************************************/
/*                                                                           */
/*                           OCO SOURCE MATERIALS                            */
/*                             IBM CONFIDENTIAL                              */
/*                                    OR                                     */
/*                        IBM CONFIDENTIAL RESTRICTED                        */
/*            WHEN COMBINED WITH THE AGGREGATED OCO SOURCE MODULES           */
/*                           FOR THIS PROGRAM PRODUCT                        */
/*                                                                           */
/*      VisualAge Generator Server for OS/2, AIX, HP-UX, and Windows NT      */
/*                          Version 3.0  5697-C28                            */
/*                    (C) COPYRIGHT IBM CORP. 1994,1997                      */
/*                                                                           */
/*****************************************************************************/
#ifndef FCWQNUM_H
#define FCWQNUM_H

#include <iostream.h>

/*-------------------------------------------------------------------------*/
/* Forward references                                                      */
/*-------------------------------------------------------------------------*/
class TraceFile;

/*-------------------------------------------------------------------------*/
/* Global overflow functions                                               */
/*-------------------------------------------------------------------------*/
void MaxOverflow();
void UserOverflow();
Bool StopOnUserOverflow();


/*-------------------------------------------------------------------------*/
/* Define some format types                                                */
/*-------------------------------------------------------------------------*/
enum decStrFmtOpt
{
  WSign = 1,
  WNegSign = 2,
  WLZeros = 4,
  WLZNegSign = 6
};

/*-------------------------------------------------------------------------*/
/* 16 byte value (with decimal                                             */
/*-------------------------------------------------------------------------*/
class quadnum : public quadlong
{
  public:

    quadnum( const int = 0 );
    quadnum( const int,
             const int );
    quadnum( const dbllong & );
    quadnum( const dbllong &,
             const int );
    quadnum( const double );
    quadnum( const long );
    quadnum( const quadlong & );
    quadnum( const char* );
    quadnum( const FCWString & );
    quadnum( const quadnum & );
    virtual ~quadnum();

    FCWString asString() const;

    quadnum & operator = ( const quadnum & );
    quadnum & operator = ( const int );
    quadnum & operator = ( const dbllong & );
    quadnum & operator = ( const quadlong & );
    quadnum & operator = ( const double );
    quadnum & operator = ( const char* );
    quadnum & operator = ( const FCWString & );

    const quadnum & operator + () const;
    quadnum operator - () const;

    quadnum & operator += ( const quadnum & );
    quadnum & operator -= ( const quadnum & );
    quadnum & operator *= ( const quadnum & );
    quadnum & operator /= ( const quadnum & );
    quadnum & operator %= ( const quadnum & );

    /*---------------------------------------------------------------------*/
    /*  quadnum binary operator                                            */
    /*---------------------------------------------------------------------*/
    friend quadnum operator + ( const quadnum &,
                                const quadnum & );
    friend quadnum operator - ( const quadnum &,
                                const quadnum & );
    friend quadnum operator * ( const quadnum &,
                                const quadnum & );
    friend quadnum operator / ( const quadnum &,
                                const quadnum & );
    friend quadnum operator % ( const quadnum &,
                                const quadnum & );

    /*---------------------------------------------------------------------*/
    /*  quadnum relational operator                                        */
    /*---------------------------------------------------------------------*/
    friend int operator == ( const quadnum &,
                             const quadnum & );
    friend int operator != ( const quadnum &,
                             const quadnum & );
    friend int operator < ( const quadnum &,
                            const quadnum & );
    friend int operator <= ( const quadnum &,
                             const quadnum & );
    friend int operator > ( const quadnum &,
                            const quadnum & );
    friend int operator >= ( const quadnum &,
                             const quadnum & );

    /*---------------------------------------------------------------------*/
    /*  quadnum functions to extract value                                 */
    /*---------------------------------------------------------------------*/
    short shortValue( const int ) const;
    short shortValueRounded( const int ) const;

    long longValue( const int ) const;
    long longValueRounded( const int ) const;

    dbllong dbllongValue( const int ) const;
    dbllong dbllongValueRounded( const int ) const;

    FCWString decStrOutput( const int,
                            const int,
                            const decStrFmtOpt = WSign ) const;

    void decfmt( char*,
                 const int,
                 const int,
                 const int ) const;
    void decfmtRounded( char*,
                        const int,
                        const int,
                        const int ) const;

    friend ostream & operator << ( ostream &,
                                   const quadnum & );
    friend TraceFile & operator << ( TraceFile &,
                                     const quadnum & );

    /*---------------------------------------------------------------------*/
    /*  other functions                                                    */
    /*---------------------------------------------------------------------*/
    void setShift( const int );
    int getShift() const;

    quadnum & negate();
    quadnum & normalize( const int );
    quadnum & round( const int );
    quadnum & absolute();

    static void initConstants();

  private:
    quadnum & truncate();
    OverflowType checkMax();

    int    _shift;
    void*  pData;
};

inline
int operator != ( const quadnum & aQuadnum1,
                  const quadnum & aQuadnum2 )
{
   return (!( aQuadnum1 == aQuadnum2 ));
}

inline
int operator <= ( const quadnum & aQuadnum1,
                  const quadnum & aQuadnum2 )
{
   return (!( aQuadnum1 > aQuadnum2 ));
}

inline
int operator >= ( const quadnum & aQuadnum1,
                  const quadnum & aQuadnum2 )
{
   return (!( aQuadnum1 < aQuadnum2 ));
}

#endif
