[ThinAir Home]
[Table of Contents]
[Testing a Generator]
[Defining New Generators]
12 Utility Functions and Classes
In order to make the ThinAir classes function properly, some utility code is
needed. This section describes these utilities.
12.1 The Secure Hash Algorithm
The SHARandGen classes require SHA code to implement. The SHA
code I used was written by Peter C. Gutmann and released into the public
domain in 1992. These functions are implemented in the files sha.c and
sha.h. Also included with the SHA code is a program shatest.c that
verifies the code was compiled correctly.
12.2 The Modulus Arithmetic Functions
In implementing the explicit modulus versions of the various congruential PRNGs,
I found problems with any modulus that is relatively prime to 232. I also
found that some combinations of multiplier and modulus would even overflow
double
s. I wrote add and multiply functions that properly dealt with the
modulus based on algorithms suggested by Rick Hoselton.
The modulus arithmetic functions are implemented in the files modarith.h
and modarith.cpp. This is not a general library of modulus-based
arithmetic. I only implemented what I needed.
- unsigned long mod_add( unsigned long a, unsigned long b, unsigned long mod )
-
Adds the two numbers
a
and b
in the mod
modulus field.
- unsigned long mod_mult( unsigned long a, unsigned long b, unsigned long mod )
-
Multiplies the two numbers
a
and b
in the mod
modulus
field.
- unsigned long mod_invert( unsigned long num, unsigned long mod )
-
Finds the multiplicative inverse of
num
in the mod
modulus
field.
- mod_result mod_add_c( unsigned long a, unsigned long b, unsigned long mod )
-
Adds the two numbers
a
and b
in the mod
modulus field
returning both the result and the quotient of the modulus operation.
- mod_result mod_mult_c( unsigned long a, unsigned long b, unsigned long mod )
-
Multiplies the two numbers
a
and b
in the mod
modulus
field returning both the result and the quotient of the modulus operation.
- mod_result mod_add_c( unsigned long a, unsigned long b )
-
Adds the two numbers
a
and b
in the 232 modulus field
returning both the result and the quotient of the modulus operation.
- mod_result mod_mult_c( unsigned long a, unsigned long b )
-
Multiplies the two numbers
a
and b
in the 232 modulus
field returning both the result and the quotient of the modulus operation.
In order to keep these functions from being too slow, I spent a small amount of
time profiling and optimizing the C code. I did not convert these routines to
assembly language because I wanted the code to remain as portable as possible.
The optimizations used should reduce the inefficiencies in the code in a
compiler-independent way. Obviously the actual effects of the optimizations
depends on the compiler used, but the current code should always be faster
than the obvious implementation. The code also has the advantage that it
returns the right answer even if it is slower than the more obvious floating
point solution.
12.3 The RingBuffer class
Some of the PRNGs in the ThinAir library must store several old values of the
generator. After coding this functionality by hand a couple of times, I
realized the a ring buffer class was in order. The RingBuffer
class is implemented in the files ringbuff.h and ringbuff.cpp.
This class is not as full-featured as I would have normally liked. However,
I felt that a small class, with less overhead would be more useful to ThinAir.
This class implements a rotating buffer of unsigned long integers.
The constructors for the RingBuffer class have the following prototype:
- explicit RingBuffer( unsigned size )
-
Creates a rotating buffer containing
size
elements.
- RingBuffer( const RingBuffer &rhs );
-
Copy constructor for the RingBuffer class.
The public interface for the RingBuffer class supports writing to and
reading from the buffer. In the spirit of the STL, this class also can create
an iterator object which allows the programmer to retain multiple entry points
into the buffer. The public interface for RingBuffer is shown below.
- void Init();
-
Initialize the ring buffer's insertion cursor.
- unsigned max_size() const;
-
Returns the size of the ring buffer.
- unsigned size() const;
-
Returns the current number of entries in the ring buffer.
- unsigned empty() const;
-
Returns
true
if the ring buffer is empty.
- void add( unsigned long val );
-
Add a new value at the current insertion point.
- RingBuffer &operator=( const RingBuffer &rhs );
-
Assignment operator for the RingBuff class.
- iterator MakeIterator( unsigned index );
-
Return an iterator that points to position
index
in the ring buffer.
- iterator begin();
-
Return an iterator that points to the beginning of the data in the ring
buffer.
- iterator end();
-
Return an iterator that points after the end of the data in the ring buffer.
- void Print( ostream &os ) const;
-
Write the current ring buffer to
os
.
- void Read( istream &is );
-
Read the current ring buffer from
is
.
The RingBuffer's iterator has all of the functionality you would expect
from an iterator. The iterator's public interface is shown below.
- iterator();
-
Default constructor.
- iterator( const iterator &rhs );
-
Copy constructor.
- unsigned Index() const;
-
Returns my index into the ring buffer.
- const unsigned long &operator *() const;
-
Return the value pointed to by this iterator in the ring buffer.
- unsigned long &operator *();
-
Return the lvalue of the position pointed to by this iterator in the ring
buffer.
- iterator operator++();
-
Preincrement the iterator.
- iterator operator++( int );
-
Postincrement the iterator.
- iterator operator-{
- -();}
Predecrement the iterator.
- iterator operator-{
- -( int );}
Postdecrement the iterator.
- iterator &operator=( const iterator &rhs );
-
Assign a new iterator to the current iterator.
- bool operator==( const iterator &rhs );
-
Tests two iterators for equality.
- bool operator!=( const iterator &rhs );
-
Tests two iterators for inequality.
For further information, contact G. Wade Johnson
(gwadej@anomaly.org).
© 1997 G. Wade Johnson.
All rights reserved.
http://www.anomaly.org/ThinAir/utility.html