#ifndef _BIGFLOAT_H
#define _BIGFLOAT_H

// Author: Sean Colombo
// Date:   10/3/2003
//
// note: maybe try to do similar functions to: http://www.perldoc.com/perl5.6/lib/Math/BigFloat.html
//

#include <iostream>
#include "BigInt.h"

using namespace std;

class BigFloat
{
  public:
    
	BigFloat();                    // default constructor, value = 0
	BigFloat(int);                 // assign an integer value
	BigFloat(float);
	BigFloat(double);
	BigFloat(BigInt);
	BigFloat(const string &);    // assign a string
	BigFloat(const BigFloat & rhs);
	const BigFloat & operator = (const BigFloat &);
	~BigFloat();

/*$f->fadd(NSTR) return NSTR            addition
  $f->fsub(NSTR) return NSTR            subtraction
  $f->fmul(NSTR) return NSTR            multiplication
  $f->fdiv(NSTR[,SCALE]) returns NSTR   division to SCALE places
  $f->fmod(NSTR) returns NSTR           modular remainder
  $f->fneg() return NSTR                negation
  $f->fabs() return NSTR                absolute value
  $f->fcmp(NSTR) return CODE            compare undef,<0,=0,>0
  $f->fround(SCALE) return NSTR         round to SCALE digits
  $f->ffround(SCALE) return NSTR        round at SCALEth place
  $f->fnorm() return (NSTR)             normalize
  $f->fsqrt([SCALE]) return NSTR        sqrt to SCALE places  */
	BigFloat add(BigFloat &rhs);
	//overload functions later to work with other types of numbers (BigInts and ints)
	BigFloat sub(BigFloat &rhs);
	BigFloat mul(BigFloat &rhs);
	BigFloat div(BigFloat &rhs, int precision);
	//BigFloat mod(BigFloat &rhs);
	BigFloat neg();
	BigFloat abs();
	void round(int precision);
	//COMPARISON OPERATORS GO HERE	
	//BigFloat normalize();
	//BigFloat sqrt(int precision);




	//accessors needed for the ostream functions
	BigInt getDigs() const;
	int getPrecision() const;
	// operators: arithmetic, relational
/*	const BigFloat & operator += (const BigFloat &);
	const BigFloat & operator -= (const BigFloat &);
	const BigFloat & operator *= (const BigFloat &);
	const BigFloat & operator *= (int num);
	const BigFloat & operator /= (const BigFloat &);
	const BigFloat & operator /= (int num);
	const BigFloat & operator %= (const BigFloat &);
	const BigFloat & operator ^= (int num);
	const BigFloat & operator ^= (const BigFloat &);

	BigFloat div(BigFloat &rhs, int precision);	// convert to quotient of this/rhs taken to precision
	BigFloat	sqrt(int precision);	// convert to own square root

	string   ToString() const;   // convert to string
	int      ToInt()    const;   // convert to int
	double   ToDouble() const;   // convert to double 
	
	int  getDig(int k) const;
	int getLeastSig() const; // returns the least significant digit


	// facilitate operators ==, <, << without friends
	bool Equal(const BigFloat & rhs)        const;
	bool LessThan(const BigFloat & rhs)     const;
	int myNumDigits;		// stores # of digits of number no longer private because
							// time complexity needed to either convert to string or
							// use loop to find number of digits
*/
	bool Equal(const BigFloat & rhs) const;
	bool LessThan(const BigFloat & rhs) const;

  private:
    
	// other helper functions
	void Normalize();
/*	bool IsNegative()  const;    // return true iff number is negative
	bool IsPositive()  const;    // return true iff number is positive
	int  NumDigits()   const;    // return # digits in number

	int  GetDigit(int k) const;
	void AddSigDigit(int value);
	void ChangeDigit(int k, int value);

	void DivideHelp(const BigFloat & lhs, const BigFloat & rhs,
                    BigFloat & quotient, BigFloat & remainder);

	*/
	// private state/instance variables
	BigInt myDigs;
	int myPrecision;
};

// free functions

ostream & operator <<(ostream &, const BigFloat &);
istream & operator >>(istream &, BigFloat &);

/*BigFloat operator +(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator -(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator *(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator *(const BigFloat & lhs, int num);
BigFloat operator *(int num, const BigFloat & rhs);
BigFloat operator /(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator /(const BigFloat & lhs, int num);
BigFloat operator %(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator ^(const BigFloat & lhs, const BigFloat & rhs);
BigFloat operator ^(const BigFloat & lhs, int num);*/

bool operator == (const BigFloat & lhs, const BigFloat & rhs);
bool operator <  (const BigFloat & lhs, const BigFloat & rhs);
bool operator != (const BigFloat & lhs, const BigFloat & rhs);
bool operator >  (const BigFloat & lhs, const BigFloat & rhs);
bool operator >= (const BigFloat & lhs, const BigFloat & rhs);
bool operator <= (const BigFloat & lhs, const BigFloat & rhs);

#endif   // _BIGFLOAT_H not defined
