DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: I T

⟦a023cba85⟧ TextFile

    Length: 23976 (0x5da8)
    Types: TextFile
    Names: »Integer.h«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z« 
        └─⟦23757c458⟧ 
            └─⟦this⟧ »libg++/g++-include/Integer.h« 

TextFile

// This may look like C code, but it is really -*- C++ -*-

/* 
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of GNU CC.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU CC General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License.   A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  
*/

#ifndef _Integer_h
#pragma once
#define _Integer_h 1

#include <stream.h>

struct IntRep                    // internal Integer representations
{
  unsigned short  len;          // current length
  unsigned short  sz;           // allocated space
  short           sgn;          // 1 means >= 0; 0 means < 0 
  unsigned short  s[1];         // represented as ushort array starting here

  friend IntRep*  Ialloc(IntRep*, const unsigned short *, int, int, int);
  friend IntRep*  Icopy_long(IntRep*, long);
  friend IntRep*  Icopy(IntRep*, IntRep*);
  friend IntRep*  Iresize(IntRep*, int);
  friend IntRep*  add(IntRep*, int, IntRep*, int, IntRep*);
  friend IntRep*  add(IntRep*, int, long, IntRep*);
  friend IntRep*  multiply(IntRep*, IntRep*, IntRep*);
  friend IntRep*  multiply(IntRep*, long, IntRep*);
  friend IntRep*  lshift(IntRep*, long, IntRep*);
  friend IntRep*  lshift(IntRep*, IntRep*, int, IntRep*);
  friend IntRep*  bitop(IntRep*, IntRep*, IntRep*, char);
  friend IntRep*  bitop(IntRep*, long, IntRep*, char);
  friend IntRep*  power(IntRep*, long, IntRep*);
  friend IntRep*  div(IntRep*, IntRep*, IntRep*);
  friend IntRep*  mod(IntRep*, IntRep*, IntRep*);
  friend IntRep*  div(IntRep*, long, IntRep*);
  friend IntRep*  mod(IntRep*, long, IntRep*);
  friend IntRep*  compl(IntRep*, IntRep*);
  friend IntRep*  sqr(IntRep*);
  friend IntRep*  pow(IntRep*, long);
  friend IntRep*  gcd(IntRep*, IntRep* y);
  friend int      compare(IntRep*, IntRep*);
  friend int      compare(IntRep*, long);
  friend int      ucompare(IntRep*, IntRep*);
  friend int      ucompare(IntRep*, long);
  friend char*    Itoa(IntRep* x, int base = 10, int width = 0);
  friend IntRep*  atoIntRep(const char* s, int base = 10);
  friend long     Itolong(IntRep*);
  friend double   Itodouble(IntRep*);
  friend int      Iislong(IntRep*);
  friend int      Iisdouble(IntRep*);
  friend long     lg(IntRep*);
};


class IntTmp;

class Integer
{
  friend class    IntTmp;
protected:
  IntRep*         rep;
public:
                  Integer();
                  Integer(long);
                  Integer(Integer&);

                  ~Integer();

  void            operator =  (Integer&);
  void            operator =  (IntTmp&);
  void            operator =  (long);

  friend int      operator == (Integer&, Integer&);
  friend int      operator == (Integer&, long);

  friend int      operator != (Integer&, Integer&);
  friend int      operator != (Integer&, long);

  friend int      operator <  (Integer&, Integer&);
  friend int      operator <  (Integer&, long);

  friend int      operator <= (Integer&, Integer&);
  friend int      operator <= (Integer&, long);

  friend int      operator >  (Integer&, Integer&);
  friend int      operator >  (Integer&, long);

  friend int      operator >= (Integer&, Integer&);
  friend int      operator >= (Integer&, long);

  IntTmp          operator -  ();
  IntTmp          operator ~  ();
  void            operator ++ ();
  void            operator -- ();

  IntTmp          operator +  (Integer&);
  IntTmp          operator +  (IntTmp&);
  IntTmp          operator +  (long);
  friend IntTmp   operator +  (long, Integer&);
  void            operator += (Integer&);
  void            operator += (long);
  IntTmp          operator -  (Integer&);
  IntTmp          operator -  (IntTmp&);
  IntTmp          operator -  (long);
  friend IntTmp   operator -  (long, Integer&);
  void            operator -= (Integer&);
  void            operator -= (long);
  IntTmp          operator *  (Integer&);
  IntTmp          operator *  (IntTmp&);
  IntTmp          operator *  (long);
  friend IntTmp   operator *  (long, Integer&);
  void            operator *= (Integer&);
  void            operator *= (long);
  IntTmp          operator /  (Integer&);
  IntTmp          operator /  (IntTmp&);
  IntTmp          operator /  (long);
  void            operator /= (Integer&);
  void            operator /= (long);
  IntTmp          operator %  (Integer&);
  IntTmp          operator %  (IntTmp&);
  IntTmp          operator %  (long);
  void            operator %= (Integer&);
  void            operator %= (long);
  IntTmp          operator << (Integer&);
  IntTmp          operator << (IntTmp&);
  IntTmp          operator << (long);
  void            operator <<=(Integer&);
  void            operator <<=(long);
  IntTmp          operator >> (Integer&);
  IntTmp          operator >> (IntTmp&);
  IntTmp          operator >> (long);
  void            operator >>=(Integer&);
  void            operator >>=(long);
  IntTmp          operator &  (Integer&);
  IntTmp          operator &  (IntTmp&);
  IntTmp          operator &  (long);
  friend IntTmp   operator &  (long, Integer&);
  void            operator &= (Integer&);
  void            operator &= (long);
  IntTmp          operator |  (Integer&);
  IntTmp          operator |  (IntTmp&);
  IntTmp          operator |  (long);
  friend IntTmp   operator |  (long, Integer&);
  void            operator |= (Integer&);
  void            operator |= (long);
  IntTmp          operator ^  (Integer&);
  IntTmp          operator ^  (IntTmp&);
  IntTmp          operator ^  (long);
  friend IntTmp   operator ^  (long, Integer&);
  void            operator ^= (Integer&);
  void            operator ^= (long);

  friend Integer& operator <? (Integer& x, Integer& y); // min
  friend Integer& operator >? (Integer& x, Integer& y); // max

// builtin Integer functions

  friend int      compare(Integer&, Integer&);  // signed comparison
  friend int      ucompare(Integer&, Integer&); // unsigned comparison

  void            negate();                     // negate in-place
  void            abs();                        // absolute-value in-place
  friend IntTmp   abs(Integer&);                // absolute value
  friend long     lg (Integer&);                // floor log base 2 of abs(x)
  friend IntTmp   sqr(Integer&);                // square
  friend Integer  sqrt(Integer&);               // floor of square root
  friend IntTmp   gcd(Integer& x, Integer& y);  // greatest common divisor
  friend IntTmp   lcm(Integer& x, Integer& y);  // least common multiple
  friend int      even(Integer&);               // true if even
  friend int      odd(Integer&);                // true if odd
  friend int      sign(Integer&);               // returns -1, 0, +1
  friend IntTmp   pow(Integer& x, Integer& y);  // x to the y power
  friend IntTmp   pow(Integer& x, long y);
  friend IntTmp   Ipow(long x, long y);         // x to the y as Integer 
  friend void     setbit(Integer& x, long b);   // set b'th bit of x
  friend void     clearbit(Integer& x, long b); // clear b'th bit
  friend int      testbit(Integer& x, long b);  // return b'th bit
  friend double   ratio(Integer& x, Integer& y);// return x/y as a double
  friend void     divide(Integer& x, Integer& y, Integer& q, Integer& r);
  friend void     divide(Integer& x, long y, Integer& q, long& r);

// coercion & conversion

  int             fits_in_long();
  int             fits_in_double();

                  operator long();
                  operator double();

  friend char*    Itoa(Integer& x, int base = 10, int width = 0);
  friend IntTmp   atoI(const char* s, int base = 10);
  
  friend istream& operator >> (istream& s, Integer& y);
  friend ostream& operator << (ostream& s, Integer& y);

// miscellany

  void            error(char* msg);
  int             OK();  
};

class IntTmp: public Integer
{
  friend class    Integer;

public:
                  IntTmp(IntRep*);
                  IntTmp(Integer&);
                  IntTmp(IntTmp&);
                  ~IntTmp();

  IntTmp          operator +  (IntTmp&);
  IntTmp          operator +  (Integer&);
  IntTmp          operator +  (long);
  friend IntTmp   operator +  (long, IntTmp&);
  IntTmp          operator -  (Integer&);
  IntTmp          operator -  (IntTmp&);
  IntTmp          operator -  (long);
  friend IntTmp   operator -  (long, IntTmp&);
  IntTmp          operator *  (Integer&);
  IntTmp          operator *  (IntTmp&);
  IntTmp          operator *  (long);
  friend IntTmp   operator *  (long, IntTmp&);
  IntTmp          operator /  (Integer&);
  IntTmp          operator /  (IntTmp&);
  IntTmp          operator /  (long);
  IntTmp          operator %  (Integer&);
  IntTmp          operator %  (IntTmp&);
  IntTmp          operator %  (long);
  IntTmp          operator << (Integer&);
  IntTmp          operator << (IntTmp&);
  IntTmp          operator << (long);
  IntTmp          operator >> (Integer&);
  IntTmp          operator >> (IntTmp&);
  IntTmp          operator >> (long);
  IntTmp          operator &  (Integer&);
  IntTmp          operator &  (IntTmp&);
  IntTmp          operator &  (long);
  friend IntTmp   operator &  (long, IntTmp&);
  IntTmp          operator |  (Integer&);
  IntTmp          operator |  (IntTmp&);
  IntTmp          operator |  (long);
  friend IntTmp   operator |  (long, IntTmp&);
  IntTmp          operator ^  (Integer&);
  IntTmp          operator ^  (IntTmp&);
  IntTmp          operator ^  (long);
  friend IntTmp   operator ^  (long, IntTmp&);


  IntTmp          operator -  ();
  IntTmp          operator ~  ();
  friend IntTmp   abs(IntTmp&);
  friend IntTmp   sqr(IntTmp&);
  friend IntTmp   pow(IntTmp&  x, long y);
};


char*             dec(Integer& x, int width = 0);
char*             oct(Integer& x, int width = 0);
char*             hex(Integer& x, int width = 0);


//#ifdef __OPTIMIZE__


inline Integer::Integer()
{
  rep = 0;
}

inline Integer::Integer(long y)
{
  rep = Icopy_long(0, y);
}

inline Integer::Integer(Integer&  y)
{
  rep = Icopy(0, y.rep);
}


inline Integer::~Integer()
{
  delete rep;
}

inline void  Integer::operator = (Integer&  y)
{
  rep = Icopy(rep, y.rep);
}

inline void  Integer::operator = (IntTmp&  y)
{
  delete rep;  rep = y.rep; y.rep = 0;
}

inline void Integer::operator = (long y)
{
  rep = Icopy_long(rep, y); 
}

inline Integer::operator long()
{ 
  return Itolong(rep);
}

inline int Integer::fits_in_long()
{
  return Iislong(rep);
}

inline Integer::operator double()
{ 
  return Itodouble(rep);
}

inline int Integer::fits_in_double()   
{
  return Iisdouble(rep);
}

inline int compare(Integer& x, Integer& y)
{
  return compare(x.rep, y.rep);
}

inline int ucompare(Integer& x, Integer& y)
{
  return ucompare(x.rep, y.rep);
}

inline int operator == (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) == 0; 
}

inline int operator == (Integer&  x, long y)
{
  return compare(x.rep, y) == 0; 
}

inline int operator != (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) != 0; 
}

inline int operator != (Integer&  x, long y)
{
  return compare(x.rep, y) != 0; 
}

inline int operator <  (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) <  0; 
}

inline int operator <  (Integer&  x, long y)
{
  return compare(x.rep, y) <  0; 
}

inline int operator <= (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) <= 0; 
}

inline int operator <= (Integer&  x, long y)
{
  return compare(x.rep, y) <= 0; 
}

inline int operator >  (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) >  0; 
}

inline int operator >  (Integer&  x, long y)
{
  return compare(x.rep, y) >  0; 
}

inline int operator >= (Integer&  x, Integer&  y)
{
  return compare(x.rep, y.rep) >= 0; 
}

inline int operator >= (Integer&  x, long y)
{
  return compare(x.rep, y) >= 0; 
}

inline IntTmp::IntTmp(IntRep* y)
{
  rep = y;
}

inline IntTmp::IntTmp(Integer& x)
{
  rep = x.rep; x.rep = 0;
}

inline IntTmp::IntTmp(IntTmp& x)
{
  rep = x.rep; x.rep = 0;
}

inline IntTmp::~IntTmp() {}

inline IntTmp  Integer::operator +  (Integer& y)
{
  return (add(rep, 0, y.rep, 0, 0));
}

inline IntTmp  Integer::operator +  (IntTmp& y)
{
  IntRep* r = add(rep, 0, y.rep, 0, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator +  (long y)
{
  return(add(rep, 0, y, 0));
}

inline IntTmp  operator +  (long  x, Integer& y)
{
  return(add(y.rep, 0, x, 0));
}

inline IntTmp  IntTmp::operator +  (Integer& y)
{
  IntRep* r = add(rep, 0, y.rep, 0, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator +  (IntTmp& y)
{
  IntRep* r = add(rep, 0, y.rep, 0, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator +  (long y)
{
  IntRep* r = add(rep, 0, y, rep); rep = 0; return r;
}

inline IntTmp  operator +  (long y, IntTmp& x)
{
  IntRep* r = add(x.rep, 0, y, x.rep); x.rep = 0; return r;
}

inline void  Integer::operator += (Integer& y)
{
  rep = add(rep, 0, y.rep, 0, rep);
}

inline void  Integer::operator += (long y)
{
  rep = add(rep, 0, y, rep);
}


inline void Integer::operator ++ ()
{
  rep = add(rep, 0, 1, rep);
}


inline IntTmp  Integer::operator -  (Integer& y)
{
  return (add(rep, 0, y.rep, 1, 0));
}

inline IntTmp  Integer::operator -  (IntTmp& y)
{
  IntRep* r = add(rep, 0, y.rep, 1, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator -  (long y)
{
  return(add(rep, 0, -y, 0));
}

inline IntTmp  operator -  (long  x, Integer& y)
{
  return(add(y.rep, 1, x, 0));
}

inline IntTmp  IntTmp::operator -  (Integer& y)
{
  IntRep* r = add(rep, 0, y.rep, 1, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator -  (IntTmp& y)
{
  IntRep* r = add(rep, 0, y.rep, 1, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator -  (long y)
{
  IntRep* r = add(rep, 0, -y, rep); rep = 0; return r;
}

inline IntTmp  operator -  (long y, IntTmp& x)
{
  IntRep* r = add(x.rep, 1, y, x.rep);  x.rep = 0; return r;
}

inline void  Integer::operator -= (Integer& y)
{
  rep = add(rep, 0, y.rep, 1, rep); 
}

inline void  Integer::operator -= (long y)
{
  rep = add(rep, 0, -y, rep);
}

inline void Integer::operator -- ()
{
  rep = add(rep, 0, -1, rep);
}

inline IntTmp  Integer::operator *  (Integer& y)
{
  return (multiply(rep, y.rep, 0));
}

inline IntTmp  Integer::operator *  (IntTmp& y)
{
  IntRep* r =  multiply(rep, y.rep, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator *  (long y)
{
  return(multiply(rep, y, 0));
}

inline IntTmp  operator *  (long  x, Integer& y)
{
  return(multiply(y.rep, x, 0));
}

inline IntTmp  IntTmp::operator *  (Integer& y)
{
  IntRep* r =  multiply(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator *  (IntTmp& y)
{
  IntRep* r =  multiply(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator *  (long y)
{
  IntRep* r = multiply(rep, y, rep); rep = 0; return r;
}

inline IntTmp  operator *  (long y, IntTmp& x)
{
  IntRep* r = multiply(x.rep, y, x.rep); x.rep = 0; return r;
}

inline void Integer::operator *= (Integer& y)
{
  rep = multiply(rep, y.rep, rep);
}

inline void Integer::operator *= (long y)
{
  rep = multiply(rep, y, rep); 
}

inline IntTmp sqr(Integer& x)
{
  return(multiply(x.rep, x.rep, 0));
}

inline IntTmp sqr(IntTmp& x)
{
  IntRep* r = multiply(x.rep, x.rep, x.rep); x.rep = 0; return r;
}

inline IntTmp  Integer::operator &  (Integer& y)
{
  return (bitop(rep, y.rep, 0, '&'));
}

inline IntTmp  Integer::operator &  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, y.rep, '&'); y.rep = 0; return r;
}

inline IntTmp  Integer::operator &  (long y)
{
  return(bitop(rep, y, 0, '&'));
}

inline IntTmp  operator &  (long  x, Integer& y)
{
  return(bitop(y.rep, x, 0, '&'));
}

inline IntTmp  IntTmp::operator &  (Integer& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '&'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator &  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '&'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator &  (long y)
{
  IntRep* r = bitop(rep, y, rep, '&'); rep = 0; return r;
}

inline IntTmp  operator &  (long y, IntTmp& x)
{
  IntRep* r = bitop(x.rep, y, x.rep, '&'); x.rep = 0; return r;
}

inline void  Integer::operator &= (Integer& y)
{
  rep = bitop(rep, y.rep, rep, '&'); 
}

inline void  Integer::operator &= (long y)
{
  rep = bitop(rep, y, rep, '&'); 
}

inline IntTmp  Integer::operator |  (Integer& y)
{
  return (bitop(rep, y.rep, 0, '|'));
}

inline IntTmp  Integer::operator |  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, y.rep, '|'); y.rep = 0; return r;
}

inline IntTmp  Integer::operator |  (long y)
{
  return(bitop(rep, y, 0, '|'));
}

inline IntTmp  operator |  (long  x, Integer& y)
{
  return(bitop(y.rep, x, 0, '|'));
}

inline IntTmp  IntTmp::operator |  (Integer& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '|'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator |  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '|'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator |  (long y)
{
  IntRep* r = bitop(rep, y, rep, '|'); rep = 0; return r;
}

inline IntTmp  operator |  (long y, IntTmp& x)
{
  IntRep* r = bitop(x.rep, y, x.rep, '|'); x.rep = 0; return r;
}

inline void Integer::operator |= (Integer& y)
{
  rep = bitop(rep, y.rep, rep, '|'); 
}

inline void  Integer::operator |= (long y)
{
  rep = bitop(rep, y, rep, '|'); 
}

inline IntTmp  Integer::operator ^  (Integer& y)
{
  return (bitop(rep, y.rep, 0, '^'));
}

inline IntTmp  Integer::operator ^  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, y.rep, '^'); y.rep = 0; return r;
}

inline IntTmp  Integer::operator ^  (long y)
{
  return(bitop(rep, y, 0, '^'));
}

inline IntTmp  operator ^  (long  x, Integer& y)
{
  return(bitop(y.rep, x, 0, '^'));
}

inline IntTmp  IntTmp::operator ^  (Integer& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '^'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator ^  (IntTmp& y)
{
  IntRep* r =  bitop(rep, y.rep, rep, '^'); rep = 0; return r;
}

inline IntTmp  IntTmp::operator ^  (long y)
{
  IntRep* r = bitop(rep, y, rep, '^'); rep = 0; return r;
}

inline IntTmp  operator ^  (long y, IntTmp& x)
{
  IntRep* r = bitop(x.rep, y, x.rep, '^'); x.rep = 0; return r;
}

inline void  Integer::operator ^= (Integer& y)
{
  rep = bitop(rep, y.rep, rep, '^'); 
}

inline void  Integer::operator ^= (long y)
{
  rep = bitop(rep, y, rep, '^'); 
}

inline IntTmp  Integer::operator /  (Integer& y)
{
  return (div(rep, y.rep, 0));
}

inline IntTmp  Integer::operator /  (IntTmp& y)
{
  IntRep* r =  div(rep, y.rep, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator /  (long y)
{
  return(div(rep, y, 0));
}

inline IntTmp  IntTmp::operator /  (Integer& y)
{
  IntRep* r =  div(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator /  (IntTmp& y)
{
  IntRep* r =  div(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator /  (long y)
{
  IntRep* r = div(rep, y, rep); rep = 0; return r;
}

inline void Integer::operator /= (Integer& y)
{
  rep = div(rep, y.rep, rep);  
}

inline void Integer::operator /= (long y)
{
  rep = div(rep, y, rep);  
}

inline IntTmp  Integer::operator %  (Integer& y)
{
  return (mod(rep, y.rep, 0));
}

inline IntTmp  Integer::operator %  (IntTmp& y)
{
  IntRep* r =  mod(rep, y.rep, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator %  (long y)
{
  return(mod(rep, y, 0));
}

inline IntTmp  IntTmp::operator %  (Integer& y)
{
  IntRep* r =  mod(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator %  (IntTmp& y)
{
  IntRep* r =  mod(rep, y.rep, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator %  (long y)
{
  IntRep* r = mod(rep, y, rep); rep = 0; return r;
}

inline void Integer::operator %= (Integer& y)
{
  rep = mod(rep, y.rep, rep);
}

inline void Integer::operator %= (long y)
{
  rep = mod(rep, y, rep);
}

inline IntTmp  Integer::operator <<  (Integer& y)
{
  return (lshift(rep, y.rep, 0, 0));
}

inline IntTmp  Integer::operator << (IntTmp& y)
{
  IntRep* r =  lshift(rep, y.rep, 0, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator <<  (long y)
{
  return(lshift(rep, y, 0));
}

inline IntTmp  IntTmp::operator <<  (Integer& y)
{
  IntRep* r =  lshift(rep, y.rep, 0, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator <<  (IntTmp& y)
{
  IntRep* r =  lshift(rep, y.rep, 0, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator <<  (long y)
{
  IntRep* r = lshift(rep, y, rep); rep = 0; return r;
}

inline void Integer::operator <<= (Integer&  y)
{
  rep = lshift(rep, y.rep, 0, rep); 
}

inline void Integer::operator <<= (long  y)
{
  rep = lshift(rep, y, rep); 
}

inline IntTmp  Integer::operator >>  (Integer& y)
{
  return (lshift(rep, y.rep, 1, 0));
}

inline IntTmp  Integer::operator >> (IntTmp& y)
{
  IntRep* r =  lshift(rep, y.rep, 1, y.rep); y.rep = 0; return r;
}

inline IntTmp  Integer::operator >>  (long y)
{
  return(lshift(rep, -y, 0));
}

inline IntTmp  IntTmp::operator >>  (Integer& y)
{
  IntRep* r =  lshift(rep, y.rep, 1, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator >>  (IntTmp& y)
{
  IntRep* r =  lshift(rep, y.rep, 1, rep); rep = 0; return r;
}

inline IntTmp  IntTmp::operator >>  (long y)
{
  IntRep* r = lshift(rep, -y, rep); rep = 0; return r;
}

inline void Integer::operator >>= (Integer&  y)
{
  rep = lshift(rep, y.rep, 1, rep);
}

inline void  Integer::operator >>= (long y)
{
  rep = lshift(rep, -y, rep); 
}

inline Integer& operator <? (Integer& x, Integer& y)
{
  return (compare(x.rep, y.rep) <= 0) ? x : y;
}

inline Integer& operator >? (Integer& x, Integer& y)
{
  return (compare(x.rep, y.rep) >= 0)?  x : y;
}

inline int sign(Integer& x)
{
  return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
}

inline IntTmp abs(Integer& x)
{
  return(Ialloc(0, x.rep->s, x.rep->len, 1, x.rep->len));
}

inline IntTmp abs(IntTmp& x)
{
  IntRep* r = x.rep; r->sgn = 1; x.rep = 0; return r;
}

inline void Integer::abs()
{
  rep->sgn = 1; 
}

inline void Integer::negate()
{
  if (rep->len != 0) rep->sgn = !rep->sgn;
}

inline IntTmp Integer::operator - ()
{
  int sgn = (rep->len == 0)? rep->sgn : !rep->sgn;
  return(Ialloc(0, rep->s, rep->len, sgn, rep->len));
}

inline IntTmp IntTmp::operator - ()
{
  IntRep* r = rep; if (r->len != 0) r->sgn = !r->sgn; rep = 0; return r;
}

inline IntTmp pow(Integer& x, long y)
{
  return(power(x.rep, y, 0));
}

inline IntTmp Ipow(long x, long y)
{
  IntRep* r = Icopy_long(0, x);  return(power(r, y, r));
}

inline IntTmp pow(Integer& x, Integer& y)
{
  long yy = long(y);   return power(x.rep, yy, 0); // not incorrect!
}

inline IntTmp pow(IntTmp& x, long y)
{
  IntRep* r = power(x.rep, y, x.rep); x.rep = 0; return r;
}

inline int even(Integer& y)
{
  return y.rep->len == 0 || !(y.rep->s[0] & 1);
}

inline int odd(Integer& y)
{
  return y.rep->len > 0 && (y.rep->s[0] & 1);
}

inline char* Itoa(Integer& y, int base = 10, int width = 0)
{
  return Itoa(y.rep, base, width);
}

inline IntTmp  atoI(const char* s, int base = 10)
{
  return atoIntRep(s, base);
}

inline ostream& operator << (ostream& s, Integer& y)
{
  return s << Itoa(y.rep);
}


inline IntTmp  Integer::operator ~ ()
{
  return compl(rep, 0);
}

inline IntTmp  IntTmp::operator ~ ()
{
  IntRep* r = compl(rep, rep); rep = 0; return r;
}

inline IntTmp  gcd(Integer& x, Integer& y)
{
  return gcd(x.rep, y.rep);
}

inline long lg(Integer& x)
{
  return lg(x.rep);
}

//#endif

#endif