::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:
class Math.Integer.Public  public Gilda:  Integer number arithmetic

  type I128  is                      &128 bit integer arithmetic.
       Hi    cell,                   &Upper 64 bits
       Lo    cell                    :Lower 64 bits

  type I256  is  Cell[3]             :256 bit integer

  type Random.Number..word           &32 bit random numbers
    is Seed   word

  type Random.Number..cell           &64 bit random numbers
    is Seed   cell

global Hash.Key( .Key ) => Hash__key( .Key ),  &Hashed index keys

       & The result is a Word; perform in a Word context.
       &
       Hash..word( .Key ) => (( .Key _* 2654435761 ) // 11 ) _* 2654435761, &


       & The result is a Word or Cell; depending on the context.
       &
       Hash..cell( .Key ) => cell{[( .Key _* 11400714819323197493 ) // 23 ] &
                                          _* 11400714819323197493 }, &


       & The reuslt is a Word or Cell; depending on the context type.
       &
       Hash..string( .Key ) => Hash.Key.String( .Key )
:
:...............................................................................



:::::::::::::::::::::::::::::::  Math.Cell  ::::::::::::::::::::::::::::::::::::
:
function TIMES..cell:  Multiply two unsigned cells into an unsigned i128.

 entry Left   cell,          &Unsigned
       Right  cell           :Unsigned

  exit I128                  :Unsigned (Left * Right)
:
:...............................................................................
:
function SQUARE..cell:  Compute unsigned Cell ^ 2 --> i128.


 entry Base     cell         :Unsigned

  exit I128                  :(Cell ^ 2)
:
:...............................................................................
:
function POPULATION..cell:  Count the number of one bits

 entry Value   cell        :Bits to be counted

  exit Count   byte        :Number of one bits
:
:...............................................................................
:
function LCM..cell:  Least common multiple

 entry A    cell,    &Unsigned pair
       B    cell     :Unsigned

  exit Lcm  cell     :Unsigned multiple
:
:...............................................................................
:
function SQUARE.MOD..cell:   Base ^ 2 mod Modulus

 entry Base     cell,        &Unsigned
       Modulus  cell         :Unsigned

  exit Square   cell         :(Base ^ 2) % Modulus
:
:...............................................................................
:
function POWER.MOD..cell:  Unsigned Base ^ Exponent mod Modulus

 entry Base     cell,       &0 ^ 0 = 1; else 0 ^ Exponent = 0
       Exp      cell,       &Base ^ 0 = 1
       Modulus  cell        :> 0; 1 always returns 0

  exit Power    cell        :(Base ^ Exponent) % Modulus

precondition
   Modulus  fault;             Cannot do arithmetic in modulus zero.
.
:...............................................................................
:
function TWO.POWER.MOD..cell:  Compute 2 ^ Exponent mod Cycle.

 entry Exponent   cell,      &Must not be 0
       Modulus    cell       :Must not be 0

  exit Power      cell       :(2 ^ Exponent) % Modulus

precondition
   Modulus   fault;             Cannot do arithmetic in modulus zero.
.
:...............................................................................
:
method PLUS.CARRY..cell:  Increment an unsigned value with carries.

change Sum     cell,           &Unsigned value to Increment
       Carry   Bit             :In - Carry in; Out - Carry out

 entry Increment = 0  cell     :Unsigned increment
:
:...............................................................................
:
method MINUS.BORROW..cell:  Decrement an unsigned value with borrowing.

change Sum     cell,           &Unsigned value to decrement
       Borrow  Bit             :In - Borrow in; Out - Borrow out

 entry Decrement = 0  cell     :Unsigned decrement
:
:...............................................................................
:
method PERFECT.POWER..cell  pure:  Rewrite an unsigned number as Base ^ Power.

change Base       cell         : in - Unsigned number to rewrite
                               :out - Rewritten base; unchanged if Power = 1

  exit Power = 1  byte         :Maximum possible exponent
:
:...............................................................................
:
method PERFECT.POWER.PRIME..cell  pure:  See if a perfect power of a prime 5 or over.

change Base       cell         : in - Unsigned number to rewrite
                               :out - Rewritten base; unchanged if Power = 1

  exit Power = 1  byte         :Maximum possible exponent
:
:...............................................................................
:
function IS.PRIME..cell:  See if a 64 bit unsigned number is prime.

 entry N      cell      :Number to test (> 1)

  exit Prime  Bit       :1 - prime; 0 - composite
:
:...............................................................................
:
function SPRP..cell:  Strong Probable Prime test to the Base

 entry N     cell,      &Unsigned odd number to test
       Base  cell       :Relative prime base to try

  exit Sprp  Bit        :0 - Proven composite; 1 - Likely prime; maybe not

precondition
   N // 1  fault  N;       Cannot test 0 or 1 for primality.
   N /\ 1  fault  N|d#;    Cannot test even numbers for primality.
.
:...............................................................................
:
function SPRP.TWO..cell:  Strong Probable Prime test to the base 2

 entry N     cell       :Number to test

  exit Sprp  Bit        :0 - Proven composite; 1 - Likely prime; maybe not

precondition
   N // 1  fault  N;       Cannot test 0 or 1 for primality.
   N /\ 1  fault  N|d#;    Cannot test even numbers for primality.
.
:...............................................................................



:::::::::::::::::::::::::::::::  Math.Word  ::::::::::::::::::::::::::::::::::::
:
function POPULATION..word:  Count the number of one bits

 entry Value   word    :Bits to be counted

  exit Count   byte    :Number of one bits
:
:...............................................................................
:
function LCM..word:  Least common multiple

 entry A    word,      &Unsigned pair
       B    word       :Unsigned

  exit Lcm  word       :Unsigned multiple
:
:...............................................................................
:
function SQUARE.MOD..word:   Base ^ 2 mod Modulus

 entry Base     word,        &Unsigned
       Modulus  word         :Unsigned

  exit Square   word         :(Base ^ 2) % Modulus
:
:...............................................................................
:
function POWER.MOD..word:  Compute Base ^ Exp mod Modulus

 entry Base    word,       &0 ^ 0 = 1; else 0 ^ Exponent = 0
       Exp     word,       &Base ^ 0 = 1
       Modulus word        :non-zero; 1 always returns 0

  exit Power   word        :(Base ^ Exponent) % Modulus

precondition
   Modulus  fault;            Cannot do arithmetic in modulus zero.
.
:...............................................................................
:
function TWO.POWER.MOD..word:  2 ^ Exponent mod Modulus

 entry Exponent   word,    &Unsigned
       Modulus    word     :Unsigned, non-zero

  exit Power      word     :(2 ^ Exponent) % Modulus

precondition
   Modulus   fault;           The modulus can not be zero.
.
:...............................................................................
:
method PERFECT.POWER..word  pure:  Rewrite an unsigned number as Base ^ Power.

change Base       word         : in - Unsigned number to rewrite
                               :out - Rewritten base; unchanged if Power = 1

  exit Power = 1  byte         :Maximum possible exponent
:
:...............................................................................
:
method PERFECT.POWER.PRIME..word  pure:  See if a perfect power of a prime 5 or over.

change Base       word         : in - Unsigned number to rewrite
                               :out - Rewritten base; unchanged if Power = 1

  exit Power = 1  byte         :Maximum possible exponent
:
:...............................................................................
:
function IS.PRIME..word:  See if a 32 bit number is prime.

 entry N          word       :Unsigned number (> 1 ) to test

  exit Prime = 0  Bit        :0 - Composite; 1 - Prime.
:
:...............................................................................
:
function SPRP..word:  Strong Probable Prime test to the base

 entry N     word,         &Unsigned odd number to test
       Base  word          :Relative prime base to try

  exit Sprp  Bit           :0 - Proven composite; 1 - Likely prime; maybe not

precondition
   N // 1  fault  N;          Cannot test 0 or 1 for primality
   N /\ 1  fault  N|d#;       Cannot test even numbers for primality
.
:...............................................................................
:
function SPRP.TWO..word:  Strong Probable Prime test to the base 2

 entry N     word         :Number to test

  exit Sprp  Bit          :0 - Proven composite; 1 - Likely prime; maybe not

precondition
   N // 1  fault  N;         Cannot test 0 or 1 for primality.
   N /\ 1  fault  N|d#;      Cannot test even numbers for primality.
.
:...............................................................................



:::::::::::::::::::::::::::  Math.Positive..cell  ::::::::::::::::::::::::::::::
:
function JACOBI..cell:  Calculate the Jacobi symbol:  (a/n)

 entry A       cell,    &Any signed integer.
       N       cell     :Unsigned odd over 2.

  exit Jacobi  cell     :0, 1, -1

precondition
   N /\ 1  fault N|d#;     Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;     Jacobi (a/n); n must be over 2.
.
:...............................................................................
:
function SIGNED.JACOBI..cell:  Calculate the Jacobi symbol:  (a/n)

 entry A       cell,          &Any signed integer
       N       cell           :Unsigned odd over 2

  exit Jacobi  cell           :  0  A  = 0 mod N
                              :  1  A ~= 0 mod N  and  A = x^2 mod N
                              : -1  A ~= 0 mod N  and  no x st A = x^2 mod N

precondition
   N /\ 1  fault N|d#;           Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;           Jacobi (a/n); n must be over 2.
.
:...............................................................................
:
function MINUS.JACOBI..cell:  Calculate the Jacobi symbol (a/n).

 entry A    cell,         &Unsigned integer which is implicitly negative.
       N    cell          :Unsigned odd over 2.

  exit J    cell          :  0  A  = 0 mod N
                          :  1  A ~= 0 mod N  and  A = x^2 mod N
                          : -1  A ~= 0 mod N  and  no x st A = x^2 mod N

precondition
   N /\ 1  fault N|d#;       Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;       Jacobi (a/n); n must be over 2.
.
:...............................................................................
:
function GCD..cell:  Find the greatest common divisor of 2 unsigned integers.

 entry Left     cell,   &if 0 return right
       Right    cell    :if 0 return left

  exit Divisor  cell    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
function GCD.ODD..cell:  Find the greatest common divisor of 2 unsigned odds.

 entry Left     cell,   &if 0 return right
       Right    cell    :if 0 return left

  exit Divisor  cell    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
function GCD.EXTENDED..cell:  Find the greatest common divisor of 2 unsigned integers.

 entry Left     cell,   &if 0 return right
       Right    cell    :if 0 return left

  exit Divisor  cell    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
method GCD.EXTENDED.SET..cell  pure:  Extended gcd where:  gcd = S * A + T * B

 entry Left   _integer,     &Unsigned
       Right  _integer      :Unsigned

  exit S = 1  _integer,     &Signed
       T = 0  _integer,     &Signed
       Gcd    _integer
:
:...............................................................................
:
function DIVIDE.ROUND..cell:  Unsigned division rounded to nearest

 entry Numerator    cell,            &Unsigned
       Denominator  cell             :Divide by zero fault if zero.

  exit Quotient     cell             :Rounded quotient
:
:...............................................................................
:
function DIVIDE.ROUNDUP..cell:  Unsigned division rounded up (ceiling)

 entry Numerator    cell,            &Unsigned
       Denominator  cell             :Divide by zero fault if zero.

  exit Quotient     cell             :Rounded quotient
:
:...............................................................................
:
function PLUS.MOD..cell:  Modular addition

 entry L   cell,       &< Modulus
       R   cell,       &< Modulus
       M   cell        :Modulus

  exit S   cell        :Modular sum
:
:...............................................................................
:
function MINUS.MOD..cell:  Modular subraction

 entry L   cell,       &< Modulus
       R   cell,       &< Modulus
       M   cell        :Modulus

  exit D   cell        :Modular difference
:
:...............................................................................



:::::::::::::::::::::::::::  Math.Positive..word  ::::::::::::::::::::::::::::::
:
function JACOBI..word:  Calculate the Jacobi symbol:  (a/n)

 entry A       word,    &Any signed integer.
       N       word     :Unsigned odd over 2.

  exit Jacobi  word     :0, 1, -1

precondition
   N /\ 1  fault N|d#;     Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;     Jacobi (a/n); n must be over 2.
.
:...............................................................................
:
function SIGNED.JACOBI..word:  Calculate the Jacobi symbol:  (a/n)

 entry A       word,          &Any signed integer
       N       word           :Unsigned odd over 2

  exit Jacobi  word           :  0  A  = 0 mod N
                              :  1  A ~= 0 mod N  and  A = x^2 mod N
                              : -1  A ~= 0 mod N  and  no x st A = x^2 mod N

precondition
   N /\ 1  fault N|d#;           Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;           Jacobi (a/n); n must be over 2.
.
:...............................................................................
:
function MINUS.JACOBI..word:  Calculate the Jacobi symbol (a/n).

 entry A    word,         &Unsigned integer which is implicitly negative.
       N    word          :Unsigned odd over 2.

  exit J    word          :  0  A  = 0 mod N
                          :  1  A ~= 0 mod N  and  A = x^2 mod N
                          : -1  A ~= 0 mod N  and  no x st A = x^2 mod N

precondition
   N /\ 1  fault N|d#;       Jacobi (a/n); n must be odd.
   N // 1  fault N|d#;       Jacobi (a/n); n must be over 2.
.
:
:...............................................................................
:
function GCD..word:  Find the greatest common divisor of 2 unsigned integers.

 entry Left     word,   &if 0 return right
       Right    word    :if 0 return left

  exit Divisor  word    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
function GCD.ODD..word:  Find the greatest common divisor of 2 unsigned odds.

 entry Left     word,   &if 0 return right
       Right    word    :if 0 return left

  exit Divisor  word    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
function GCD.EXTENDED..word:  Find the greatest common divisor of 2 unsigned integers.

 entry Left     word,   &if 0 return right
       Right    word    :if 0 return left

  exit Divisor  word    :Common divisor; 1 or 0 if none.
:
:...............................................................................
:
method GCD.EXTENDED.SET..word  pure:  Extended gcd where:  gcd = S * A + T * B

 entry Left   _integer,     &Unsigned
       Right  _integer      :Unsigned

  exit S = 1  _integer,     &Signed
       T = 0  _integer,     &Signed
       Gcd    _integer
:
:...............................................................................
:
function DIVIDE.ROUND..word:  Unsigned division rounded to nearest

 entry Numerator    word,            &Unsigned
       Denominator  word             :Divide by zero fault if zero.

  exit Quotient     word             :Rounded quotient
:
:...............................................................................
:
function DIVIDE.ROUNDUP..word:  Unsigned division rounded up (ceiling)

 entry Numerator    word,            &Unsigned
       Denominator  word             :Divide by zero fault if zero.

  exit Quotient     word             :Rounded quotient
:
:...............................................................................
:
function PLUS.MOD..word:  Modular addition

 entry L   word,       &< Modulus
       R   word,       &< Modulus
       M   word        :Modulus

  exit S   word        :Modular sum
:
:...............................................................................
:
function MINUS.MOD..word:  Modular subraction

 entry L   word,       &< Modulus
       R   word,       &< Modulus
       M   word        :Modulus

  exit D   word        :Modular difference
:
:...............................................................................



::::::::::::::::::::::::::::::  Safe.Cell  :::::::::::::::::::::::::::::::::::::
:
function SAFE.PLUS:  Signed 64 bit sum; fault if overflow.

 entry Left   cell,            &Signed
       Right  cell             :Signed

  exit Sum    cell             :Signed (Left + Right)
:
:...............................................................................
:
function SAFE.MINUS:  Signed 64 bit difference; fault if overflow.

 entry Left   cell,            &Signed
       Right  cell             :Signed

  exit Delta  cell             :Signed (Left - Right)
:
:...............................................................................
::
function SAFE.TIMES:  Signed 64 bit product; fault on overflow.

 entry Left     cell,          &Signed
       Right    cell           :Signed

  exit Product  cell           :Signed (Left * Right)
:
:...............................................................................
:
function SAFE.DIVIDE:  Signed 64 bit division; fault on overflow.

 entry Left      cell,         &Signed
       Right     cell          :Signed

  exit Quotient  cell          :Signed (Left * Right)
:
:...............................................................................
:
function SAFE.UPLUS:  Unsigned cell product; fault if overflow.

 entry Left   cell,            &Unsigned
       Right  cell             :Unsigned

  exit Sum    cell             :Unsigned (Left + Right)
:
:...............................................................................
:
function SAFE.UMINUS:  Unsigned 64 bit difference; fault if overflow.

 entry Left   cell,            &Unsigned
       Right  cell             :Unsigned

  exit Delta  cell             :Unsigned (Left - Right)
:
:...............................................................................
:
function SAFE.UTIMES:  Unsigned 64 bit product; fault on overflow.

 entry Left   cell,            &Unsigned
       Right  cell             :Unsigned

  exit Times  cell             :Unsigned (Left * Right)
:
:...............................................................................



:::::::::::::::::::::::::::::::  Math.I128  ::::::::::::::::::::::::::::::::::::
:
function FORM..I128:  Format as: #<High>_<Low>  (uppercase hex)

 entry I128,                   &Value to format
       Format = ""  string     :Ignored

  exit Form         string     :Only hex is supported.
:
:...............................................................................
:
method SET  pure:  Initialize a 128 bit number.

  exit I128                    :I128 bit number initialized at 0

 entry Lo = 0    cell,         &Lower 64 bits
       Hi = 0    cell          :Upper 64 bits
:
:...............................................................................
:
function TO.DOUBLE:  Approximate an unsigned 128 bit integer as a Double.

 entry I128                    :Unsigned 128 bit integer

  exit Double                  :Approximate value
:
:...............................................................................
:
method SIGNED64  pure:  Sign extend 64 bits to 128 bits.

  exit I128                    :Sign extended result

 entry Cell = 0                :Signed 64 bit value
:
:...............................................................................
:
method POSITIVE64  pure:  Zero extend 64 bits to 128 bits.

  exit I128                    :Unsigned extended result

 entry Cell = 0                :Lower 64 bits
:
:...............................................................................
:
function ABSOLUTE..I128:  Get the absolute value of a signed 128 bit integer.

 entry Value      I128         :Signed

  exit Absolute   I128         :Unsigned
:
:...............................................................................
:
function NEGATE..I128:  Negate a signed 128 bit integer.

 entry I128                    :Signed 128 bit integer

  exit Negative  I128          :-I128
:
:...............................................................................
:
function COMPLEMENT..I128:  Logical not operation

 entry I128                    :Unsigned source

  exit Negative  I128          :Unsigned result
:
:...............................................................................
:
function POPULATION:  Count the number of one bits.

 entry I128                    :Population value

  exit Count   parcel          :Number of one bits
:
:...............................................................................
:
function SQUARE.ROOT..I128:  Square root of an unsigned 128 bit integer.

 entry N      I128             :Unsigned 128 bit integer

  exit Root   cell             :Unsigned square root
:
:...............................................................................
:
method LOG2..I128  pure:  binary log of an unsigned 128 bit integer.

 entry I128                    :Unsigned

  exit Log2    byte            :Log base 2
:
:...............................................................................
:
function LOG2.DOUBLE:  Binary log of an unsigned 128 bit integer

 entry I128                    :Number to take the log2

  exit Log2    double          :Log2 as a double
:
:...............................................................................
:
method PLUS..I128  pure:  Twos complement 128 bit addition.

change I128                    :Signed or unsigned 128 bit integer; Accumulator

 entry N    I128               :Number to add; Twos complement increment
:
:...............................................................................
:
method PLUS64..I128  pure:  Signed 128 bit addition.

change Left    I128            :Sum

 entry Right   cell            :Addend
:
:...............................................................................
:
method PLUS.CARRY:  Increment an unsigned value with carries.

change I128,                   &Unsigned accumulator
       Carry   Bit             :Carry in and carry out

 entry Increment   I128        :Unsigned addend
:
:...............................................................................
:
method MINUS..I128  pure:  Twos complement 128 bit subtraction.

change I128                    :Signed or unsigned 128 bit integer; Accumulator

 entry N    I128               :Number to subtract; Twos complement decrement
:
:...............................................................................
:
method MINUS64..I128  pure:  Signed 128 bit subtraction.

change Left    I128            :Accumulator

 entry Right   cell            :Signed decrement
:
:...............................................................................
:
function UTIMES:  Unsigned product:  i128 * i128 --> i256

 entry Left    I128,           &Unsigned
       Right   I128            :Unsigned

  exit Product I256            :Left * Right; Truncated to 128 bits
:
:...............................................................................
:
function UTIMES64..I128:  Unsigned product: i128 * cell --> i128

 entry Left   I128,            &Unsigned
       Right  cell             :Unsigned

  exit I128                    :Left * Right; Truncated to 128 bits
:
:...............................................................................
:
function SQUARE:  Unsigned square:  i128^2 --> i128

 entry Base    I128            :Unsigned

  exit I128                    :Base^2; Truncated to 128 bits
:
:...............................................................................
:
function POWER:  Unsigned exponentiation:  i128 ^ i128

 entry Base       I128,        &Unsigned
       Exponent   I128         :Unsigned

  exit Power      I128         :Base ^ Exponent; Truncated to 128 bits
:
:...............................................................................
:
function POWER64:  Unsigned exponentiation:  i128 ^ i128

 entry Base       I128,        &Unsigned
       Exponent   cell         :Unsigned

  exit Power      I128         :Base ^ Exponent; Truncated to 128 bits
:
:...............................................................................
:
method TWO.POWER:  Unsigned exponentiation:  2^byte

  exit I128                    :Unsigned

 entry Power    byte           :2^Power; Truncated to 128 bits
:
:...............................................................................
:
method UDIVIDE64..I128  pure:  Divide an unsigned 128 bit integer by a 64 bit integer.

change I128                    :In - Numerator; Out - quotient

 entry Denominator  cell       :64 bit denominator

  exit Mod          cell       :I128 % Denominator
:
:...............................................................................
:
function MOD64..I128:  Unsigned 128 bit integer mod an unsigned 64 bit integer

 entry I128,                   &Unsigned 128 bit numerator
       Modulus  cell           :64 bit modulus

  exit Mod      cell           :I128 % Modulus
:
:...............................................................................
:
function MOD32..I128:  Unsigned 128 bit integer mod an unsigned 32 bit integer

 entry I128,                   &Unsigned 128 bit numerator
       Modulus  word           :32 bit modulus

  exit Mod      word           :I128 % Modulus
:
:...............................................................................
:
function GCD..I128:  Find the GCD of a two 128 bit unsigned integers.

 entry Left     I128,          &Unsigned
       Right    I128           :Unsigned

  exit Divisor  I128           :Greatest common divisor
:
:...............................................................................
:
function GCD.ODD..I128:  Find the GCD of a two 128 bit unsigned odd integers.

 entry Left     I128,          &Unsigned odd value
       Right    I128           :Unsigned odd value

  exit Divisor  I128           :Greatest common divisor
:
:...............................................................................
:
method SHIFT.LEFT..I128  pure:  Shift a 128 bit integer left.

change I128                    :Unsigned 128 bit integer shifted left

 entry Shift = 1  word         :Number of bits to shift
:
:...............................................................................
:
method SHIFT.RIGHT..I128  pure:  Shift a 128 bit integer right.

change I128                    :Unsigned 128 bit integer shifted right

 entry Shift = 1  word         :Number of bits to shift
:
:...............................................................................
:
function AND..I128:  128 bit logical and

 entry I128,                   &Unsigned 128 bit integer
       N     I128              :Unsigned 128 bit integer

  exit And   I128              :I128 /\ N
:
:...............................................................................
:
function OR..I128:  128 bit logical or

 entry I128,                   &Unsigned 128 bit integer
       N     I128              :Unsigned 128 bit integer

  exit Or    I128              :I128 \/ N
:
:...............................................................................
:
function XOR..I128:  128 bit logical xor

 entry I128,                   &Unsigned 128 bit integer
       N     I128              :Unsigned 128 bit integer

  exit Xor   I128              :I128 -- N
:
:...............................................................................
:
function IS.ZERO:  See if a 128 bit integer is zero.

 entry I128                    :Value to test

  exit Zero   Bit              :Set if zero
:
:...............................................................................
:
function IS.BIT..I128:  Test a bit.

 entry I128,                   &Value to test
       Index  byte             :Bit to test; low order bit is zero

  exit Bit                     :Selected bit value
:
:...............................................................................
:
function IS.PERFECT.POWER..I128:  Is a number an integral power.

 entry N        I128,          &Number to check
       Power    parcel         :Power to check (a small exponent)

  exit Perfect  Bit            :N is a perfect power
:
:...............................................................................
:
function EQUAL64:  Compare a 128 bit to a 64 bit unsigned integer.

 entry Left   I128,            &Unsigned
       Right  cell             :Unsigned

  exit Equal  Bit              :1 if Left = Right
:
:...............................................................................
:
function LESS..I128:  Compare two 128 bit unsigned integers.

 entry Left   I128,            &Unsigned
       Right  I128             :Unsigned

  exit Less = 0  Bit           :1 if Left < Right
:
:...............................................................................
:
function LESS64..I128:  Compare a 128 bit unsigned integer to a 64 bit integer.

 entry Left   I128,            &Unsigned
       Right  cell             :Unsigned

  exit Less   Bit              :1 if Left < Right
:
:...............................................................................
:
function LESS.EQUAL..I128:  Compare two 128 bit unsigned integers.

 entry Left    I128,           &Unsigned
       Right   I128            :Unsigned

  exit Less    Bit             :1 if Left <= Right
:
:...............................................................................
:
function LESS.EQUAL64:  Compare a 128 bit unsigned integer to a 64 bit integer.

 entry Left   I128,            &Unsigned
       Right  cell             :Unsigned

  exit Less   Bit              :1 if Left <= Right
:
:...............................................................................
:
function OVER:  Compare two 128 bit unsigned integers.

 entry Left   I128,            &Unsigned
       Right  I128             :Unsigned

  exit Over   Bit              :1 if Left > Right
:
:...............................................................................
:
function OVER64:  Compare a 128 bit unsigned integer to a 64 bit integer.

 entry Left   I128,            &Unsigned
       Right  cell             :Unsigned

  exit Over   Bit              :1 if Left > Right
:
:...............................................................................
:
function OVER.EQUAL:  Compare a 128 bit unsigned integer to a 64 bit integer.

 entry Left    I128,           &Unsigned
       Right   I128            :Unsigned

  exit Over  Bit               :1 if Left >= Right
:
:...............................................................................
:
function OVER.EQUAL64:  Compare a 128 bit unsigned integer to a 64 bit integer.

 entry Left    I128,           &Unsigned
       Right   cell            :Unsigned

  exit Over     Bit            :1 if Left >= Right
:
:...............................................................................




::::::::::::::::::::::::::::::::  Factor.Cell  :::::::::::::::::::::::::::::::::
:
function FIRST.FACTOR..cell:  First Factor of a 64 bit unsigned integer (single thread).

 entry N       cell        :An odd number over 2 to factor.

  exit Factor  word        :The lowest prime factor of N; 0 if N is prime.

precondition
   N // 1  fault  N;          Cannot factor zero or one.
   N /\ 1  fault  N;          Cannot factor an even number.
.
:...............................................................................
:
sequence FACTOR..cell  pure:  Factors of a 64 bit unsigned integer.

 entry N       cell        :The number to factor.

  exit Factor  cell        :Factors ordered from low to high; none if prime.

precondition
   N   fault  N;              Cannot factor zero.
.
:...............................................................................
:
sequence FACTOR.WHEEL  pure:  A fast sequence of mostly prime numbers.

 entry Start  cell         :Start the sequence here (over 31).

  exit Odd    cell         :Primes and odds with no factor 31 and under.

precondition
   Start // 5  fault  Start;                The wheel must start over 31.
.
:...............................................................................
:
sequence PRIME..cell  pure:  32 bit prime numbers.

 entry From = 3  cell     :Skip 2 by default.

  exit Prime     cell     :Prime numbers => From; the last prime is 4294967291
:
:...............................................................................
:
function SQUARE.FORM..cell:  Factor a 64 bit unsigned number by Shank's square form method.

 entry N       cell    :An odd composite > 1 (test for primality first).

  exit Factor  word    :0 if not factored; else a factor (may be composite).
:
:...............................................................................
:
function REDUCE.FACTOR..cell:  Find the smallest factor of a factor.

 entry Factor  cell        :A factor or cofactor of a number.

  exit Small   cell        :The smallest factor.
:
:...............................................................................
:
method TRIAL.DIVISION.RANGE..cell  pure:  Factor an odd number by trial division.

 entry N      cell          :N should be over 16 bits.

  exit Factor = 0   word    :The next factor found, 0 if none.

change Lower  word          :Lowest factor to try (must be a prime => 13).

 entry Upper  word          :The last factor to try (any integer > Lower).
:
:...............................................................................
:
method TRIAL.DIVISION..cell  pure:  Trial divide up through a 16 bit maximum.

 entry N       cell    :Odd 64 bit number to factor.

  exit Factor  word    :0 or a Factor.

change Lower   word      : In - First prime to try; must be <= Max;
                         :Out - the factor or next prime over Max.

precondition
   Lower _<= _max  fault Lower; The lower bound exceed the maximum.
.
:...............................................................................
:
function TRIAL.DIVISION.271..cell:  Trial divide from 3 up through 271 using GCD.

 entry N      cell         :Odd 64 bit number to factor

  exit Factor word         :Lowest factor; 0 if none found
:
:...............................................................................
:
function TRIAL.ROOT49..cell:  Trial division from 277 up and near the root.

 entry N       cell,       &A 49 bit number to factor; prefactored through 271
       I = 57  word        :Index to the first reciprocal to try
                           :Use 57 to start trial division with 277.

  exit F       word        :Factor or zero if none found

precondition
   N // 49 = 0   fault N|d#;  F Cannot factor numbers over 2^49.
.
:...............................................................................
:
function TRIAL.ROOT64:  Trial division from 277 and near the root.

 entry N       cell        :A 64 bit number to factor; prefactored through 271.

  exit Factor  word        :Factor or zero if none found.

precondition
   N // 64 = 0   fault N|d#;    Cannot factor numbers over 2^64.
.
:...............................................................................
:
method TRIAL.DIVISION49  pure:  Trial divide up through a 16 bit maximum.

 entry N       cell      :Odd 49 bit number to factor.

  exit Factor  word      :0 or a Factor.

change Lower   word      : In - Index to the first reciprocal to try.
                         :Out - the factor or next prime over Max.

precondition
   N // 49 = 0  fault N|d#; FAULT:  Cannot factor numbers over 49 bits.

   Lower _< Prime.Reciprocal49.Size   &The lower index exceed the maximum.
            fault Lower
.
:...............................................................................
:
function FORM.FACTOR:  Get the factors of a number in decimal.

 entry N            cell,      &Unsigned number over 1 to factor
       Format = ""  string     :Output if a prime

  exit Factor       string     :Formated prime; else:  2^k * odd ...

precondition
   N // 1  fault N;               Cannot factor zero or one.
.
:...............................................................................



::::::::::::::::::::::::::::::::  Factor.Word  :::::::::::::::::::::::::::::::::
:
function FIRST.FACTOR..word:  First Factor of a 32 bit unsigned integer.

 entry N       word      :Unsigned odd number over 2 to factor.

  exit F = 0   word      :The lowest prime factor of N; 0 if N is prime.

precondition
   N // 1  fault  N;        Cannot factor zero or one.
   N /\ 1  fault  N;        Cannot factor an even number.
.
:...............................................................................
:
sequence FACTOR..word  pure:  Factors of a 32 bit unsigned integer.

 entry N   word      :Unsigned; The number to factor (not zero or one).

  exit F   word      :The factors ordered from low to high; none if prime.

precondition
   N   fault;           Cannot factor zero.
.
:...............................................................................
:
sequence FACTOR.WHEEL..word  pure:  A fast sequence of mostly prime numbers.

 entry Start  word             :Start the sequence here (over 31).

  exit Odd    word             :Primes and odds with no factor 31 and under.

precondition
   Start // 5  fault  Start;    The wheel must start over 31.
.
:...............................................................................
:
sequence PRIME..word  pure:  32 bit prime numbers.

 entry From = 3  word      :Skips 2 when using the default.

  exit Prime     word      :Prime numbers => From; the last prime is 4294967291
:
:...............................................................................
:
function SQUARE.FORM..word:  Factor a 32 bit unsigned number by Shank's square form method.

 entry N      word         :An odd composite > 1 (test for primality first).

  exit F = 0  word         :Factor or 0 if none.
:
:...............................................................................
:
function TRIAL.ROOT49:  Trial division from 271 to cube root and near the root.

 entry N       word        :A composite number to factor.

  exit F       word        :Factor or zero if none found and N has 2 factors.
:
:  Note that Trial.Root.Go49 returns the lowest factor if near the root.
:  This is because factors near the root will be prime.
:  They are under 16 bits and trail division has been done past 8 bits.
:  If they were composite they would have a factor under 8 bits.
:
:  Trial division is performed without the use of division.
:  Small factor trials use prime reciprocals and floating point multiplication.
:  Factors near the root are tested with integer addition and subtraction.
:  These operations are overlapped using hand tuned assembler.
:...............................................................................




::::::::::::::::::::::::::::::::  Factor.Parcel  :::::::::::::::::::::::::::::::
:
function FIRST.FACTOR..parcel:  First factor of a 16 bit unsigned integer.

 entry N       parcel     :Unsigned; > 1; Number to factor

  exit Factor  parcel     :Factor (2 to 251) or 0 if prime

precondition
   N // 1  fault  N;         FAULT:  Cannot factor zero or one.
.
:...............................................................................
:
sequence PRIME  pure:  16 bit prime numbers.

 entry From = 3  parcel      :Skip 2 by default.

  exit Prime     parcel      :Prime numbers => From.
:
:...............................................................................



:::::::::::::::::::::::::::::::::  Math.Random  ::::::::::::::::::::::::::::::::
:
method SEED..Random.Number..word  pure  alias Seed..word:  Reset the uniform generator.

change Random.Number..word     :Update the generator state.

 entry Seed = 0       word :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method SEED..Random.Number..cell  pure  alias Seed..cell:  Reset the uniform generator.

change Random.Number..cell     :Update the generator state.

 entry Seed = 0        cell :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method SEED..cell  pure:  Reset the uniform generator.

change Random.Number..cell     :Update the generator state.

 entry Seed = 0        cell :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method SEED..word  pure:  Reset the uniform generator.

change Random.Number..word     :Update the generator state.

 entry Seed = 0       word :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method UNIFORM..Random.Number..cell  pure:  Uniform random number in a Word or Cell.

change Random.Number..cell     :Update the generator state.

  exit Random         cell  :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method UNIFORM..Random.Number..word  pure:  Uniform random number in a Word or Cell.

change Random.Number..word     :Update the generator state.

  exit Random         word  :Seed value or 0 for system to pick a seed.
:
:...............................................................................
:
method LOG2..Random.Number..cell  pure:  Log2 distribution random number in a Word or Cell.

change Random.Number..cell     :Update the generator state.

  exit Random         cell :Random number with Log2 distribution.

:...............................................................................
:
method LOG2..Random.Number..word  pure:  Log2 distribution random number in a Word or Cell.

change Random.Number..word     :Update the generator state.

  exit Random         word :Random number with Log2 distribution.

:...............................................................................
:
method RANGE..Random.Range..cell  pure:  Uniform random number in a range.

change Random.Range..cell     :Range established by Random.Range.

  exit Random        cell :Uniform random number within the range.
:
:...............................................................................
:
method RANGE..Random.Range..word  pure:  Uniform random number in a range.

change Random.Range..word     :Range established by Random.Range.

  exit Random        word :Uniform random number within the range.
:
:...............................................................................
:
method RANDOM.RANGE..Random.Range..cell  pure:  Establish uniform random numbers in a range.

change Random.Range..cell    :Update the state of the generator.

 entry Here  = -1   cell, &Either bound (default is maximum type size).
       There =  0   cell, &The other bound value in the range.
       Seed  =  0   cell  :Seed value for the generator (0 for timer).
:
:...............................................................................
:
method RANDOM.RANGE..Random.Range..word  pure:  Establish uniform random numbers in a range.

change Random.Range..word    :Update the state of the generator.

 entry Here  = -1   word, &Either bound (default is maximum type size).
       There =  0   word, &The other bound value in the range.
       Seed  =  0   word  :Seed value for the generator (0 for timer).
:
:...............................................................................
:


:::::::::::::::::::::::::::::::::  Math.Hash  ::::::::::::::::::::::::::::::::
:
method HASH.KEY..cell:  Hash a String into a 64 bit key.

change Key     cell        :Hashed 128 bit key

 entry Value   string      :Password string
:
:...............................................................................
:
method HASH.KEY..I128:  Hash a String into a 128 bit key.

  exit Key     I128        :Hashed 128 bit key

 entry Value   string      :Password string
:
:...............................................................................
:
method HASH.KEY..I256:  Hash a String into a 256 bit key.

  exit Key     I256        :Hashed 256 bit key

 entry Value   string      :Password sting
:
:...............................................................................
:
method HASH.STRING..cell:  Hash a String into a 64 bit key.

  exit Key     cell        :Hashed 128 bit key

 entry Value   string      :Password string
:
:...............................................................................
:
method HASH.STRING..I128:  Hash a String into a 128 bit key.

  exit Key     I128        :Hashed 128 bit key

 entry Value   string      :Password string
:
:...............................................................................
:
method HASH.STRING..I256 pure:  Hash a String into a 256 bit key.

  exit Key     I256        :Hashed 256 bit key.

 entry Value   string      :Password string
:
:...............................................................................
:
function HASH.KEY.STRING:  Hash a string of bytes, returning a 64 bit value.

 entry Key    string       :Byte sequence to be hashed

  exit Hash   cell         :Hash value
:
:...............................................................................

end