home *** CD-ROM | disk | FTP | other *** search
- Very Large Numbers - VLN
-
- This Object Class allows the user to compute to very high
- precision. The unique feature of this Object class is that
- numbers are supported up to 1000 decimal digits or more,
- limited only by available memory. While only integer data
- is supported, scaled arithmetic allows numbers to be
- used as small as 1 x 10 ^ -1000 or smaller.
-
- Several basic operations are provided such as add,
- subtract, multiply and divide. Further useful
- operations include 2^n, 10^n, nth-power and nth-Root.
- Write Hexadecimal and Write Decimal procedures are included.
-
- Object definition:
- ))))))))))))))))))))))))))))))))))))))))))
- )) ))
- )) pWordArray = ^tWordArray ))
- )) tWordArray = object ))
- )) array[1..vlsize] of word; ))
- )) end; ))
- )) ))
- )) pVryLrgNo =^tVryLrgNo; ))
- )) tVryLrgNo = object ))
- )) count : integer; ))
- )) max : integer; ))
- )) sign : integer; ))
- )) tVLN : tWordArray; ))
- )) ))
- )) procedures and functions. ))
- )) end; ))
- )) ))
- ))))))))))))))))))))))))))))))))))))))))))
-
- One problem in defining this data type, that can contain
- more than a thousand bytes, is that there is no best size
- for 'vlsize' the maximum allowed size. Some applications
- will need a few numbers of immense size while others will
- need many but not so big.
-
- The user, if he does nothing special may use the default size
- of 1000 words (which allows 5300 decimal digits) for all variables
- in his program.
- A way is illustrated to use less memory assuming he knows how large the numbers will actually be. This method uses
- GETMEM( name, size)
-
- In the process of initializing a VLN variable, the programmer also
- specifies 'MAX' the maximum size expected and this is tested in
- all arithmetic procedures.
-
- The main program is responsible for OpenTempRegs at the start
- and CloseTempRegs at the end as well as disposing of any dynamic
- variables that are created. This is to allow the user to specify maximum
- size of the VLN before the arithmetic working registers are initialized.
-
- {------------------------------------------------------------}
- VLN Fields
-
- count - the number of tVLN words used, tVLN[count] is
- expected to be non-zero, while higher words are - undefined
-
- max - The number of tVLN words for which space is assigned
- Writing to a higher word may cause a crash.
-
- sign - " +1" signifies positive
- " -1" signifies negative
-
- tVLN - A set of "1 . . max" words representing a positive
- integer. tVLN[1] is least significant and tVLN[count] is most
- significant. If tVLN[count] is zero then the same VLN number can be
- represented by the same data set except with count= count-1.
- This is a situation that is awkward but all algorithms included here
- should accept the redundant representations.
-
- -------------------------------------------------------------
- Description of procedures and functions
-
- constructor Init( cnt, maxC, sgn : integer; pnew :pWordArray);
- The normal place to set "max" := maxC. Most arithmetic routines
- check the current "count" against "max" This constructor calls
- Set Value (below)
-
- procedure SetVal( cnt, sgn : integer; pnew :pWordArray);
- Assumes that max is previously set.
- Count is set to cnt
- Sign is set to sgn
- tVLN is set to contents of pnew
-
- procedure SetSmall(n:integer); { set immediate to 16 bits, signed }
- same as SetVal, except operand limited to +/- integer.
- Count is set to 1
- Sign" set to sign of n
- tVLN[1] is set to absv(n)
-
- procedure Clear( n : integer);
- Count is set to 0
- Sign is set to 1
- max" and "tVLN" unchanged
-
- procedure Copy( other : pVryLrgNo ); { copy other into self }
- Previous values are discarded except Max" is retained.
- Sign, Count and tVLN terms are taken from "other"
- if other.count > self.max then an error is called.
-
- procedure WriteHex;
- Write to screen, Most significant data first
-
- procedure WriteDecimal ( mode : integer);
- Write to screen in decimal format.
- In mode=0 Most significant data is first
- in mode=1 least significant data is first
- in mode=2 only one or two most significant terms are shown
-
- procedure AddBy(other : pVryLrgNo);
- The present value is added to "other".
- Count & Sign are set to calculated values.
- tVLN[i] will contain new calculated data.
-
- procedure AddN(n:integer);
- Same as Addby except that the operand is a provided integer.
-
- procedure SubBy(other : pVryLrgNo);
- The value "other" is subtracted from the present value.
- Count & Sign are set to calculated values.
- tVLN[i] will contain new calculated data.
-
- procedure SubN(n:integer);
- Same as Subby except that the operand is a provided integer.
-
- procedure TwosComplAbs( cnt : integer );
- Sign and Count are unchanged.
- Each term of tVLN from 1 to count is changed with terms converted
- by the equation --- t := 65536-t up to and including the
- first non-zero term. Subsequent terms are converted by the
- equation --- t := 65535-t up to and including tVLN[count]
-
-
- procedure MulBy(other : pVryLrgNo);
- The present value is multiplied by "other".
- Count & Sign are set to calculated values.
- tVLN[i] will contain new calculated data.
-
- procedure MultN(n:integer);
- Same as Mulby except that the operand is a provided integer.
-
- procedure DivBy( dvsr, remnd : pVryLrgNo);
- The present value is divided by "other".
- Count & Sign are set to calculated values.
- tVLN[i] will contain new calculated data.
-
- procedure DivN(n:integer);
- Same as Addby except that the operand is a provided integer.
-
- procedure TwoNth(n:integer );
- Discards present count, sign, and tVLN words and sets
- Sign is set to 1,
- Count is set to (n div 16) + 1
- all tVLN terms < count-1 = 0
- tVLN[count] = 2^(n mod 16)
-
- procedure TenNth(n:integer );
- Discards present count, sign, and tVLN words
- Sign is set to 1
- If n=1 then count is set to 1 and tVLN[1] is set to 10
- If n>1 then tVLN becomes integer 10 is multiplied by itself
- (n-1) times
-
- procedure NthRoot(n:integer );
- The present value is used to calculate it's Nth root
- Sign is set to 1;
- Count and tVLN are calculated
- In general the number of significant bits is decreased and is
- inversely proportional to n.
-
- procedure NthPower(n:integer );
- The present value is used to calculate it's Nth power.
- Sign is set to 1;
- Count and tVLN are calculated
- In general the number of significant bits is increased and is
- directly proportional to n.
-
- function FindnoBinDig : integer; { how many binary digits }
- Counts the number of significant digits, binary with each
- term less than count = 16 and using the actual number of
- bits in tVLN[count]
-
- procedure BigSHL(cnt : integer); {shift left by words }
- The entire VLN is multiplied by 2^16. Count is incremented
- and tVln[1] becomes 0.
-
- procedure MultiSHL(sf_cnt : integer); {shift left by bits }
- Will shift the entire VLN by 1 to 15 bits. If tVLN[count]
- overflows, then count is incrementd and the overflow bits
- are placed in the new tVLN[count].
-
- procedure Shr1Bit; {shift right one bit}
- The entire VLN is divided by 2.
- If tVLN[count] was initially = 1 then count is decremented.
-
- procedure ShL1Bit; {shift left one bit}
- The entire VLN is multiplied by 2.
- If the word tVLN[count] overflows then count is incremented
- and the new highest term is set to 1.
-
- function FindDivShift(other : pVryLrgNo) : integer;
- Finds required shift in preparation for dividing. This allows
- the divisor to be initially positioned so that it is not larger
- than the dividend. Ideally the divisor would be
- positioned so that it at least half as large as the dividend.
- However this routine only looks at the most significant terms
- of dividend and divisor so it may start smaller than optimum.
-
- procedure GetRandom(binCnt : integer);
- Returns a random number with bincnt binary bits. The tVLN terms
- are defined using pascal's random function. In addition the
- top term is masked to give the number of significant bits
- in that word as calculated by "bincnt" mod 16.
-
- procedure Recount;
- Tests each tVLN term starting at "count" and working down until
- a non-zero term is found. Count is decremented to point
- to that non-zero word or is set to zero if no non-zero terms are
- found.
-
-
- Other routines for manipulating the Class tVryLrgNo;
-
- function MaxOfW (a,b : word) : word;
- Returns a or b whichever is larger;
-
- function IsGrEqAbs (n1, n2 : pVryLrgNo): boolean; {
- Returns true if variable pointed to by n1 is
- larger than variable pointed to by n2, without considering
- sign, (treating both as though they were positive numbers)
-
- function IsEqAbs (n1, n2 : pVryLrgNo): boolean;
- Returns true if variable pointed to by n1 is
- equal to variable pointed to by n2, without considering
- sign, (treating both as though they were positive numbers)
-
- procedure HexWord ( w : word; var pS : pchar4);
- Returns a 4-character array;
- pchar4 is defined as --- array[0..4]of char;
-
-
- procedure SetWkSize (n:integer);
- Sets the size that internal arithmetic registers will be
- initialized to when calling ' OpenTempRegs '
-
- function GetWkSize : integer;
- Retreives the current value of wksize
-
- procedure CloseTempRegs ;
- Initializes several temporary arithmetic registers using
- GetMem and with size = 'wksize'
-
- procedure OpenTempRegs ;
- Disploses of several temporary arithmetic registers using
- FreeMem and with size = 'wksize'
-
- procedure CallError (s:String);
- Prints the string 's'
-
- ----------------------------------------------------------------------------------
- Included files
-
- VLNCLS.PAS defines the Class - tVryLrgNo
- FACTRL calculates factorials
- FIBNACII calculates the Fibonacii series
- MATRIX2 Creates an array of reciprocals
- PI_4_96 calculates PI
- SQROOT calculates square roots to variable precision
- ROOTS calculates specified root to 36 decimal digits
-
-
- ----------------------------------------------------------------------------------
- This program is given to public without restriction
- ----------------------------------------------------------------------------------
-
-
-