// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: float64.cpp 
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: Doug Gaer   
// File Creation Date: 09/12/1997  
// Date Last Modified: 07/23/1998
// Copyright (c) 1997 Douglas M. Gaer
// ----------------------------------------------------------- // 
// ------------- Program Description and Details ------------- // 
// ----------------------------------------------------------- // 
/*
The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
All those who put this code or its derivatives in a commercial
product MUST mention this copyright in their documentation for
users of the products in which this code or its derivative
classes are used. Otherwise, you have the freedom to redistribute
verbatim copies of this source code, adapt it to your specific
needs, or improve the code and release your improvements to the
public provided that the modified files carry prominent notices
stating that you changed the files and the date of any change.

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.

The FLOAT64 class is used to represent 64 bit signed double
precision floating point values independently of the operating
system or hardware platform used. It works by separating a 64-bit
value into eight separate byte values and reordering the bytes
highest-order to lowest-order. A FLOAT64 type has a positive
limit of 1.7E+308 and a negative limit of 1.7E-308 with 15-digit
precision. NOTE: In order to maintain the correct byte ordering
on PC based, Intel x86 family, systems the __X86__ macro must be
defined at compile time.

In a double precision floating point number, the binary info is
stored within a total of 64 bits. The first bit contains the sign
of the mantissa (0 for positive and 1 for negative). The next 11
bits store the exponent, and the remaining 52 bits provide the
mantissa, giving an approximate decimal precision of 15 digits.
*/
// ----------------------------------------------------------- //   
#include <string.h>
#include <memory.h>
#include "float64.hpp"
#include "ehandler.hpp"

// This include file is no longer used
// #include "machine.hpp"

// Enable this macro for Intel x86 family (Littel-Endian)
// ===============================================================
// #ifndef __X86__
// #define __X86__
// #endif  

FLOAT64::FLOAT64(__DPFLOAT__ val)
{
  UnPackBits(val);
}

FLOAT64::FLOAT64(const FLOAT64& ob)
{
  memmove((void *)byte, (const void *)ob.byte, sizeof(__DPFLOAT__));
}

FLOAT64& FLOAT64::operator=(const FLOAT64& ob)
{
  memmove((void *)byte, (const void *)ob.byte, sizeof(__DPFLOAT__));
  return *this;
}

FLOAT64& FLOAT64::operator=(const __DPFLOAT__ val)
{
  UnPackBits(val);
  return *this;
}

FLOAT64::operator __DPFLOAT__() const
{
  return PackBits();
}

__DPFLOAT__ FLOAT64::PackBits() const
{
  double buf;
  double *nval = new double;

#ifdef __X86__     // Big to littel endian conversion for X86 processors
  FLOAT64 ob;  
  ob.byte[7] = byte[0]; 
  ob.byte[6] = byte[1];
  ob.byte[5] = byte[2];
  ob.byte[4] = byte[3];
  ob.byte[3] = byte[4];
  ob.byte[2] = byte[5];
  ob.byte[1] = byte[6];
  ob.byte[0] = byte[7];
  memmove((void *)nval, (const void *)ob.byte, sizeof(__DPFLOAT__));
#else
  memmove((void *)nval, (const void *)byte, sizeof(__DPFLOAT__));
#endif
  
  buf = *nval;
  delete nval;

  return buf;
}

void FLOAT64::UnPackBits(__DPFLOAT__ val)
{
  __DPFLOAT__ *dptr = &val;
  char *ptr = new char[sizeof(__DPFLOAT__)+1];

  memmove((void *)ptr, (const void *)dptr, sizeof(__DPFLOAT__));

#ifdef __X86__     // Littel to big endian conversion for X86 processors
  byte[7] = ptr[0];
  byte[6] = ptr[1];
  byte[5] = ptr[2];
  byte[4] = ptr[3];
  byte[3] = ptr[4];
  byte[2] = ptr[5];
  byte[1] = ptr[6];
  byte[0] = ptr[7];
#else                
  byte[0] = ptr[0];
  byte[1] = ptr[1];
  byte[2] = ptr[2];
  byte[3] = ptr[3];
  byte[4] = ptr[4];
  byte[5] = ptr[5];
  byte[6] = ptr[6];
  byte[7] = ptr[7];
#endif
  
  delete [] ptr;
}

FLOAT64 FLOAT64::operator++(int) // Postfix
{
  FLOAT64 val_before(*this); 
  operator=(*this + 1);
  return val_before;
}
 
FLOAT64 FLOAT64::operator--(int) // Postfix
{
  FLOAT64 val_before(*this); 
  operator=(*this - 1);
  return val_before;
}

void FLOAT64::operator/=(const FLOAT64 &fp)
{
  if(fp == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / fp);
}

void FLOAT64::operator/=(const __DPFLOAT__ &fp)
{
  if(fp == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / fp);
}

void FLOAT64::operator/=(const __LWORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

    operator=(*this / i);
}

void FLOAT64::operator/=(const __ULWORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / i);
}

void FLOAT64::operator/=(const __WORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / i);
}

void FLOAT64::operator/=(const __SWORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / i);
}

void FLOAT64::operator/=(const __UWORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / i);
}

void FLOAT64::operator/=(const __USWORD__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / i);
}

void FLOAT64::operator/=(const __SBYTE__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / (__DPFLOAT__)i);
}

void FLOAT64::operator/=(const __UBYTE__ &i)
{
  if(i == 0)
#ifdef CPP_EXCEPTIONS
    throw CDivideByZero();
#else
    Error->SignalException(EHandler::DivideByZero);
#endif

  operator=(*this / (__DPFLOAT__)i);
}

int operator==(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() == b.PackBits();
}

int operator==(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() == bf;
}

int operator==(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() == bl;
}

int operator==(const __LWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() == bl;
}

int operator==(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() == bl;
}

int operator==(const __WORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits();
}

int operator==(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() == bl;
}

int operator==(const __SWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() == bl;
}

int operator==(const __UWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __USWORD__ &bl)
{
  return  a.PackBits() == bl;
}

int operator==(const __USWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl;
}

int operator==(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits(); 
}

int operator==(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl;
}

int operator==(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits(); 
}

int operator!=(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() != bf;
}

int operator!=(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __LWORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __WORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __SWORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __UWORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __USWORD__ &bl)
{
  return a.PackBits() != bl;
}

int operator!=(const __USWORD__ &al, const FLOAT64 &b)
{
  return al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() != (__DPFLOAT__)bl;
}

int operator!=(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al != b.PackBits();
}

int operator!=(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() != (__DPFLOAT__)bl;
}

int operator!=(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al != b.PackBits();
}

int operator<(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() < b.PackBits();
}

int operator<(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() < bf;
}

int operator<(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af < b.PackBits();
}

int operator<(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __LWORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __WORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __SWORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __UWORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __USWORD__ &bl)
{
  return a.PackBits() < bl;
}

int operator<(const __USWORD__ &al, const FLOAT64 &b)
{
  return al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() < (__DPFLOAT__)bl;
}

int operator<(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al < b.PackBits();
}

int operator<(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() < (__DPFLOAT__)bl;
}

int operator<(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al < b.PackBits();
}

int operator>(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() > b.PackBits();
}

int operator>(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() > bf;
}

int operator>(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af > b.PackBits();
}

int operator>(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __LWORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __WORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __SWORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __UWORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __USWORD__ &bl)
{
  return a.PackBits() > bl;
}

int operator>(const __USWORD__ &al, const FLOAT64 &b)
{
  return al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() > (__DPFLOAT__)bl;
}

int operator>(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al > b.PackBits();
}

int operator>(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() > (__DPFLOAT__)bl;
}

int operator>(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al > b.PackBits();
}

int operator<=(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() == b.PackBits() || a.PackBits() < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() == bf || a.PackBits() < bf;
}

int operator<=(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af == b.PackBits() || af < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __LWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __WORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __SWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __UWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __USWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() < bl;
}

int operator<=(const __USWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl ||  a.PackBits() < (__DPFLOAT__)bl;
}

int operator<=(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits() || (__DPFLOAT__)al < b.PackBits();
}

int operator<=(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl ||  a.PackBits() < (__DPFLOAT__)bl;
}

int operator<=(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits() || (__DPFLOAT__)al < b.PackBits();
}

int operator>=(const FLOAT64 &a, const FLOAT64 &b)
{
  return a.PackBits() == b.PackBits() || a.PackBits() > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __DPFLOAT__ &bf)
{
  return a.PackBits() == bf || a.PackBits() > bf;
}

int operator>=(const __DPFLOAT__ &af, const FLOAT64 &b)
{
  return af == b.PackBits() || af > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __LWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __LWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __ULWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __ULWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __WORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __WORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __SWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __SWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __UWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __UWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __USWORD__ &bl)
{
  return a.PackBits() == bl || a.PackBits() > bl;
}

int operator>=(const __USWORD__ &al, const FLOAT64 &b)
{
  return al == b.PackBits() || al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __SBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl || a.PackBits() > (__DPFLOAT__)bl;
}

int operator>=(const __SBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits() || (__DPFLOAT__)al > b.PackBits();
}

int operator>=(const FLOAT64 &a, const __UBYTE__ &bl)
{
  return a.PackBits() == (__DPFLOAT__)bl || a.PackBits() > (__DPFLOAT__)bl;
}

int operator>=(const __UBYTE__ &al, const FLOAT64 &b)
{
  return (__DPFLOAT__)al == b.PackBits() || (__DPFLOAT__)al > b.PackBits();
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //
