 /*
##########################################################################
#                                                                        #
# Program: IeeeCC754                                                     #
#                                                                        #
# Description:                                                           #
#   IeeeCC754 or IEEE 754 Compliance Checker is a precision and range    #
#   independent tool to test whether an implementation of                #
#   floating-point arithmetic (in hardware or software) is compliant     #
#   with the principles of the IEEE 754-854 floating-point standards.    #
#   You can find out more about the testing tool IeeeCC754 at            #
#                                                                        #
#         http://www.win.ua.ac.be/~cant/ieeecc754.html                   #
#                                                                        #
#   This tool is in parts based on and greatly benefited from the        #
#   the program FPTEST developed by Jerome Coonen. For a full            #
#   description of the extensions to FPTEST and a reference to           #
#   the original Coonen program, please refer to the URL given above.    #
#   For the options available with the program IeeeCC754 and its         #
#   compatibility with David Hough's hexadecimal UCB format, we          #
#   also refer to the file readme.usage.                                 #
#                                                                        #
#  Usage: see readme.usage                                               #
#                                                                        #
#  Responsible authors:                                                  #
#         Brigitte Verdonk                                               #
#         Annie Cuyt                                                     #
#                                                                        #
#  Contributors:                                                         #
#         Tarun Agarwal (05-07/2002)                                     #
#         Stefan Becuwe (07/2000- )                                      #
#         Johan Bogo (10/1998-09/1999)                                   #
#         Wim Dausy (10/2002-09/2003)                                    #
#         Tim Gevers (10-12/2000)                                        #
#         Matthias Huesken (02/2004- )                                   #
#         Debby Ooms (10/1996-09/1997)                                   #
#         Geert Vermuyten (10/1996-09/1997)                              #
#         Dennis Verschaeren (09/1996-06/2000)                           #
#                                                                        #
#  Copyright (C) 2000,2001,2002,2003,2004,2005                           #
#                Universiteit Antwerpen                                  #
#                                                                        #
#  This program can be obtained from the authors, free, but WITHOUT ANY  #
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or     #
#  FITNESS FOR A PARTICULAR PURPOSE.                                     #
#                                                                        #
#  Contact:                                                              #
#       Brigitte.Verdonk@ua.ac.be                                        #
#       Departement Wiskunde en Informatica                              #
#       Universiteit Antwerpen                                           #
#       Middelheimlaan 1                                                 #
#       B-2020 Antwerpen, Belgium                                        #
#                                                                        #
##########################################################################


$Id: Conversiontest.cc 79 2006-03-29 12:28:52Z sbecuwe $

                                                                     
 */
/**     \file
 *      \brief Specific definitions of Class DriverFloatRepr for MpIeee conversions
 */

#include <cmath>
#include <cstring>
#include <cstdlib>
#include <DriverFloatRepr.h>
#include <sstream>
#include <ArithmosIO.hh>

DriverFloatRepr DriverFloatRepr::roundto(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee res(FPParams(2, (unsigned)dsizeMant,dsizeExp)),op(FPParams(2, sizeMant,sizeExp));
  

  op=to();

  SetLibRound();
  SetLibEnvironment();
  res = op;
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}


DriverFloatRepr DriverFloatRepr::copyto(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee res(FPParams(2, (unsigned)dsizeMant,dsizeExp)),op(FPParams(2, (unsigned)sizeMant,sizeExp));
  

  op=to();

  SetLibRound();
  SetLibEnvironment();
  res = op;
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}


DriverFloatRepr DriverFloatRepr::rint(){
  MpIeee::fpEnv.setRadix(2);
  MpIeee op(FPParams(2, sizeMant,sizeExp));
  op= to();
  SetLibRound();
  SetLibEnvironment();
  op.rint();
  GetLibExceptions();
  DriverFloatRepr r(op);
  return r;
}

DriverFloatRepr DriverFloatRepr::ri(){
  long int l;
  MpIeee::fpEnv.setRadix(2);
  MpIeee op(FPParams(2, sizeMant, sizeExp));
  op= to();
  SetLibRound();
  SetLibEnvironment();
  l = op.toInt();
  GetLibExceptions();
  DriverFloatRepr r(l);
  return r;
}

DriverFloatRepr DriverFloatRepr::ru(){
  unsigned long int l;
  MpIeee::fpEnv.setRadix(2);
  MpIeee op(FPParams(2, sizeMant, sizeExp));
  op= to();
  SetLibRound();
  SetLibEnvironment();
  l = op.toUnsignedInt();
  GetLibExceptions();
  DriverFloatRepr r(l);
  return r;
  ;
}

DriverFloatRepr DriverFloatRepr::rI(){
  long long int l;
  MpIeee::fpEnv.setRadix(2);
  MpIeee op(FPParams(2, sizeMant, sizeExp));
  op= to();
  SetLibRound();
  SetLibEnvironment();
  l = op.toLongLong();
  GetLibExceptions();
  DriverFloatRepr r(l);
  return r;
  ;
}

DriverFloatRepr DriverFloatRepr::rU(){
  unsigned long long int l;
  MpIeee::fpEnv.setRadix(2);
  MpIeee op(FPParams(2, sizeMant, sizeExp));
  op= to();
  SetLibRound();
  SetLibEnvironment();
  l = op.toUnsignedLongLong();
  GetLibExceptions();
  DriverFloatRepr r(l);
  return r;
}

DriverFloatRepr DriverFloatRepr::ci(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee::fpEnv.setPrecision((unsigned)dsizeMant);
  MpIeee::fpEnv.setExponentSize(dsizeExp);
  int l = toint();
  MpIeee res(l);
  SetLibRound();
  SetLibEnvironment();
  res.fromInteger(l);
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}

DriverFloatRepr DriverFloatRepr::cu(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee res(FPParams(2, (unsigned)dsizeMant,dsizeExp));
  unsigned int l = touint();
  SetLibRound();
  SetLibEnvironment();
  res.fromInteger(l);
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}

DriverFloatRepr DriverFloatRepr:: cI(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee res(FPParams(2, (unsigned)dsizeMant,dsizeExp));
  long long l = tolonglong();
  SetLibRound();
  SetLibEnvironment();
  res.fromInteger(l);
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}

DriverFloatRepr DriverFloatRepr:: cU(int dsizeExp,int dsizeMant,int dhidden){
  MpIeee::fpEnv.setRadix(2);
  MpIeee res(FPParams(2, (unsigned)dsizeMant,dsizeExp));
  unsigned long long l = toulonglong();
  SetLibRound();
  SetLibEnvironment();
  res.fromInteger(l);
  GetLibExceptions();
  DriverFloatRepr r(res);
  return r;
}

DriverFloatRepr DriverFloatRepr:: b2d(int prec){

  DriverFloatRepr res;
  // only create new string if there isn't already one
  if (res.decimal == NULL)
    res.decimal = new char[maxstr];
  string decimal;

  MpIeee::fpEnv.setRadix(2);
  MpIeee::fpEnv.setPrecision(sizeMant);
  MpIeee::fpEnv.setExponentSize(sizeExp);

  MpIeee op;
  op = to();

  SetLibRound();
  SetLibEnvironment();
  decimal = op.toDecimal(prec);
  GetLibExceptions();

  int k=0;
  while (decimal[k]) {
    res.decimal[k]=decimal[k];
    k++;
  }
  res.decimal[k]='\0';

  return res;
}

DriverFloatRepr DriverFloatRepr:: b2d(unsigned prec){

  DriverFloatRepr res;
  // only create new string if there isn't already one
  if (res.decimal == NULL)
    res.decimal = new char[maxstr];
  string decimal;

  MpIeee::fpEnv.setRadix(2);
  MpIeee::fpEnv.setPrecision(sizeMant);
  MpIeee::fpEnv.setExponentSize(sizeExp);

  MpIeee op;
  op = to();

  SetLibRound();
  SetLibEnvironment();
  decimal = op.toDecimal(prec);
  GetLibExceptions();

  string preexp, postexp;
  ostringstream osiexp;
  string::size_type dot, exp;
  int iexp;

  if (decimal[0] != '-')
    decimal.insert(decimal.begin(), '+');
  
  if (decimal.find("^-") < decimal.length())
    decimal.replace(decimal.find("^-"), 2, "E-");
  else if (decimal.find("^") < decimal.length())
    decimal.replace(decimal.find("^"), 1, "E+");
  else
    decimal += "E+0";
  
  dot=decimal.find(".");
  exp=decimal.find("E");

  if (dot < decimal.length())
    {
      decimal.replace(dot, 1, "");
      preexp=decimal.substr(0, exp);
      postexp=decimal.substr(exp, decimal.length()-exp);
      iexp=atoi(postexp.c_str());
      iexp -= (exp-dot-1);
      
      if (iexp >= 0)
	osiexp << "+";
      osiexp << iexp;
      
      preexp += osiexp.str();
      decimal = preexp;
    }

  int k=0;
  while (decimal[k]) {
    res.decimal[k]=decimal[k];
    k++;
  }
  res.decimal[k]='\0';

  return res;
}
//end of multi line adjustment

DriverFloatRepr DriverFloatRepr::d2b() {
  MpIeee::fpEnv.setRadix(2);
  MpIeee::fpEnv.setPrecision(sizeMant);
  MpIeee::fpEnv.setExponentSize(sizeExp); 
  MpIeee op(FPParams(2, sizeMant,sizeExp));
  SetLibRound();
  SetLibEnvironment();
  op.fromDecimal(decimal);
  GetLibExceptions();    
  DriverFloatRepr res(op);
  return res;
}
