




                              

                          HugeCalc

        Arbitrary Accuracy Arithmetic Package for C++






                      by Zvika Ben-Haim








Introduction 


What Is HugeCalc? 
      You  can program in C/C++. The computer's power is  in
your hands. You can make the computer do anything... or  can
you?  How  about  simple, integer arithmetic operations?  No
problem? OK, fine, write a program that tells me how much  6
to the 50th power is.
      Or  is  that  a problem? Do I hear you mumbling  about
overflows, limitations of 32-bit computers, and the  maximum
size  that  can be stored in a long int?  Or perhaps  you're
thinking  of the measly 15-digit accuracy of double  floats?
Either way, you've got to admit that the basic data types in
computer languages have serious limitations when it comes to
large numbers.
      That's  where HugeCalc comes in. When you  incorporate
this   package  in  your  project,  you  can  make   integer
calculations in any size you want. What's more,  you've  got
complete  accuracy in your calculations.  That's  right:  no
more exponential notation, no more approximate results.  You
want  to  know  what  the 200th digit of  a  number  is?  No
problem.  You  now have the ultimate in integer  computation
power.

Who This Package Is For 
      This programming package assumes you are familiar with
the basics of C++, such as input/output using C++ I/O stream
classes.  You do not have to be an expert on object-oriented
programming in C++. Basically the HugeCalc classes work just
like  ordinary integers, so even C programmers can  use  the
package with minimal hassle.

Shareware Information 
      This  package  is shareware. You may test  it  for  no
charge,  and  you  may  copy  and distribute  the  shareware
version,  as  long  as  you don't charge  anything  for  the
distribution. If you find this package to be useful,  or  if
you  intend to use it in any type of commercial product, you
are  expected to register. Registering costs a mere $10, and
will give you the following advantages, not included in  the
shareware version:
 Get the  newest  available,  fully-registered  version  of
  HugeCalc.
 Support for all major PC operating systems, including DOS,
  Microsoft  Windows  3.x,   Microsoft   Windows   NT,   and
  Microsoft Windows 95.
 Support for writing large  programs  using  bigger  memory
  models, such as the Compact, Large and Huge memory models.
 A printed manual  containing  the  latest  information  on
  HugeCalc, sample programs, and more.
 Debugging support for HugeCalc programs via the Internet.
 Guaranteed _no_ junk mail.
 A clean conscience!

System Requirements 
      HugeCalc  has  been  tested with various  versions  of
Borland  C++ and is assumed to work with other compilers  as
well. It is entirely ANSI C++ compliant and uses no "modern"
ANSI  C++  functions (such as templates and error  trapping)
which may not be available in older compilers.
     The shareware version includes support for DOS programs
only,  in  the  tiny,  small and medium memory  models.  The
registered  version includes support for DOS,  Windows  3.x,
Windows  95,  and  Windows NT, and  for  all  memory  models
supported  by  Borland  C++: tiny, small,  medium,  compact,
large and huge.


Using HugeCalc 

      Great care was taken to ensure that HugeCalc would  be
just as easy to use as ordinary integers. Using HugeCalc  is
easy. Three simple steps are involved:

 Add the appropriate  object  file  in  your  project  file
  (.PRJ)  or make file (.MAK) to tell the compiler  you  are
  using the HugeCalc library.
 Include  the  file HUGECALC.HPP in all  modules  using
  HugeCalc objects.
 Declare HugeCalc objects as HugeInt (instead of int).

Adding the Object File 
      To  use HugeCalc, you must incorporate the appropriate
object file in your program. The correct object file can  be
determined from the following table. Entries marked with  an
asterisk (*) are available with the registered version only.


Operating System             Model     Object File

DOS                          Tiny      HCALCT.OBJ
DOS                          Small     HCALCS.OBJ
DOS                          Medium    HCALCM.OBJ
DOS*                         Compact*  HCALCC.OBJ
DOS*                         Large*    HCALCL.OBJ
DOS*                         Huge*     HCALCH.OBJ
Windows 3.x*                 Large*    HCALCW16.OBJ
Windows NT or Windows 95*    --*       HCALCW32.OBJ


     In  the  Borland C++ Integrated Development Environment
(IDE),  adding  the object file is done by  pressing  Insert
while in the Project window, and then selecting the file you
want  to include. Other compilers may have other methods  of
including  files.  Consult  your compiler  manual  for  more
information.

Including the Header File 
     All modules that use the HugeCalc classes and functions
must  include the file HUGECALC.HPP. This is done by  adding
the line

#include "d:\path\hugecalc.hpp"

to  the top of the module, where d:\path is the location  of
the   file   HUGECALC.HPP.  This  file   contains   function
prototypes  and  class  definitions belonging  to  HugeCalc.
Although  it is a standard C++ header file written  in  text
mode,  do  not  change it in any way.  Doing  so  may  cause
unpredictable  results,  since the function  prototypes  may
incorrectly reference the object file.

Declaring and Using HugeCalc Objects 
     Working with HugeCalc is easy. Like ordinary variables,
HugeInts must be declared before use, and may be initialized
with  a  constant or with another variable. If they are  not
initialized,  their  initial value is 0.  An  example  of  a
declaration is:

HugeInt a=1;
HugeInt b, c=a; // b=0, c=1
     
     All ordinary operators can be used with HugeInts in the
same  way  as they are used for integers. For instance,  the
following  statements  are  legal  for  both  integers   and
HugeInts.  Operator precedence follows the  same  rules  for
both data types.

cin >> b >> z;
a = 4*b + z;
if(abs(a)>=z-4)
   cout << a;

     For  your  convenience, a list  of  all  functions  and
operators follows. In this list, a and b are assumed  to  be
declared as either HugeInt objects, or ordinary int objects,
or  one of each, and n is assumed to be an int. ostr  is  an
object  of  class ostream (such as cout),  and  istr  is  an
object of class istream (such as cin). However, since  there
is  no  cast (implicit or explicit) from HugeInts  to  ints,
ints  cannot  be  placed on the left side of any  assignment
operator which involves HugeInts.

Name            Usage Ex.   Return Value / Purpose

Absolute Value  abs(a)      'a' with a positive sign
Addition        a+b         Sum of 'a' and 'b'
Add Assign      a+=b        Equivalent to a=a+b
Assignment      a=b         Copies 'b' into 'a'
Digit Value     a[n]        Value of nth digit in 'a'
Equality        a==b        TRUE if 'a' equals 'b'
Greater/Equal   a>=b        FALSE if 'a' is less than 'b'
Greater than    a>b         TRUE if 'a' is greater than 'b'
Input           istr>>a     Reads # from 'istr' into 'a'
Length          a.length()  Number of digits in 'a'
Less/Equal      a<=b        FALSE if 'a' is greater than 'b'
Less than       a<b         TRUE if 'a' is less than 'b'
Mult. Assign    a*=b        Equivalent to a=a*b
Multiplication  a*b         Product of 'a' and 'b'
Negation        -a          Returns 'a' with opposite sign
Output          ostr<<a     Outputs value of 'a' into 'ostr'
Subtraction     a-b         Difference between 'a' and 'b'
Subt. Assign    a-=b        Equivalent to a=a-b


Example Programs 
     An  example program, containing both an executable  and
all  files  needed  to  create that executable  (source  and
Borland C++ 3.1 make file), is included for those of you who
like  to take a look at working code before they start their
own  programs. The code was originally written  for  Borland
C++  3.1,  but  should  work  on any  common  C++  compiler,
assuming  the  make  file is modified  for  that  particular
compiler.


Special Operators and Functions 

     This  section  describes  the  functions  and operators
which can be used with  HugeInts,  but  which  do  not  have
equivalents in ordinary ints.
1.Absolute  Value: This function is identical to  the  abs()
  function  included in many header files, but applies  only
  to  HugeInts. It returns the positive value of the HugeInt
  passed   to  it.  For  instance,  abs((HugeInt)5)  returns
  (HugeInt)5,  but  abs((HugeInt)(-3))  returns  (HugeInt)3.
  To   run  this  function  with  an  integer  constant   or
  expression,  it  is recommended that you  explicitly  cast
  the  constant to type HugeInt, as shown above.  This  will
  tell  the  compiler  you  wish to run  the  HugeInt  abs()
  function,  and  not  other overloaded instances  of  abs()
  which may be present in your program.
2.Length:  This member function receives no parameters,  and
  returns  the  number of digits in the calling object.  For
  instance,  if  a  is  the HugeInt number  593052049,  then
  a.length() returns 9.
3.Digit  Value: This operator functions in the same  way  as
  the  array  selection operator, and behaves as though  the
  HugeInt  were  an  array of digits. In other  words,  a[n]
  returns   the  nth  digit  in  a.  Note  that  the   least
  significant  digit is stored first, so that  a[0]  is  the
  least  significant digit in a. If n is  greater  than  the
  number  of  digits in a, the operator returns 0.  To  find
  out  the  number  of digits in a HugeInt, use  the  member
  function length().


Memory Considerations 

     Naturally,  HugeCalc  data takes up  more  memory  than
ordinary integers. The default size of HugeCalc integers  is
between  301  and 304 bytes, depending on the  platform  and
compiler.  This allows the use of integers up to a  size  of
300  digits.  The maximum number of digits  can  be  changed
during  compile time, and the size of each HugeCalc  integer
will be changed accordingly.
     All  HugeCalc data is allocated statically by  default.
If  you experience problems with memory limitations, such as
a  Fix-up  Overflow error during the link, these  steps  may
help  solve  your problem. They are ranked from  easiest  to
hardest to implement.
(1) Make  sure  all  your  modules are using the same memory
  model. In particular, ensure that the HugeCalc module  you
  included is the one required for the memory model you  are
  using.
(2) If  you  are  using  a  16-bit  compiler (i.e.,  DOS  or
  Windows  3.x),  change the memory model to Large  or  Huge
  (available  with the registered version). This allows  the
  compiler  to  break  down the data segment  into  multiple
  segments,  and basically means you can use more  than  64K
  of static data in your program.
(3) Allocate HugeCalc variables dynamically.  This  is  done
  using operator new.
  For instance, HugeInt *a = (HugeInt*) new HugeInt;
  When  you are done using a dynamically allocated variable,
  use  operator  delete to free the memory  associated  with
  it.  Consult  your  C++  manual for  more  information  on
  dynamic memory allocation.
(4) If  allocating  HugeCalc  variables  dynamically doesn't
  solve  your  problem,  you  do  not have enough accessible
  RAM.  In  DOS,  this  can be solved by using EMS or XMS to
  to  allocate  some of your memory. In Windows, this can be
  done by allocating your memory from the global heap, using
  the GlobalAlloc() function.



Contacting the Author 

      HugeCalc  was originally written for my own  purposes,
and  only later on did I decide to release it to the public.
However, I welcome comments, suggestions, flames, and  other
types  of  harassment from any and all of you. I am  not  so
naive as to think anyone will register this package, but  if
you  want  to surprise me, then go ahead. I also  have  some
other shareware products, including games, which I would  be
happy  to  share with you. I can be reached on  the  net  at
zvikabh@rotem.technion.ac.il.

