109 lines
2.6 KiB
Plaintext
109 lines
2.6 KiB
Plaintext
note
|
|
description: "Summary description for {INTEGER_X_RANDOM}."
|
|
author: "Colin LeMahieu"
|
|
date: "$Date$"
|
|
revision: "$Revision$"
|
|
quote: "Letting lawyers make laws is like letting doctors make diseases. - Anonymous"
|
|
|
|
deferred class
|
|
INTEGER_X_RANDOM
|
|
|
|
inherit
|
|
INTEGER_X_FACILITIES
|
|
LIMB_MANIPULATION
|
|
SPECIAL_COMPARISON
|
|
SPECIAL_ARITHMETIC
|
|
SPECIAL_UTILITY
|
|
|
|
feature
|
|
|
|
urandomb (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; nbits: INTEGER)
|
|
-- Generate a uniformly distributed random integer in the range 0 to 2^`n'-1, inclusive.
|
|
-- `state' must be initialized by calling one of the randinit functions before invoking this function.
|
|
local
|
|
size: INTEGER_32
|
|
do
|
|
size := bits_to_limbs (nbits)
|
|
target.resize (size)
|
|
state.randget (target.item, 0, nbits)
|
|
size := normalize (target.item, 0, size)
|
|
target.count := size
|
|
ensure
|
|
target.bits <= nbits
|
|
end
|
|
|
|
urandomm (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; n: READABLE_INTEGER_X)
|
|
-- Generate a uniform random integer in the range 0 to n-1, inclusive.
|
|
-- `state' must be initialized by calling one of the randinit functions before invoking this function.
|
|
local
|
|
rp: SPECIAL [NATURAL_32]
|
|
rp_offset: INTEGER
|
|
np: SPECIAL [NATURAL_32]
|
|
np_offset: INTEGER
|
|
nlast: INTEGER
|
|
nbits: INTEGER
|
|
size: INTEGER
|
|
count: INTEGER
|
|
pow2: BOOLEAN
|
|
cmp_l: INTEGER
|
|
overlap: BOOLEAN
|
|
junk: NATURAL_32
|
|
carry: CELL [NATURAL_32]
|
|
do
|
|
create carry.put (0)
|
|
size := n.count.abs
|
|
if size = 0 then
|
|
(create {DIVIDE_BY_ZERO}).raise
|
|
end
|
|
np := n.item
|
|
nlast := size - 1
|
|
pow2 := pow2_p (n.item [nlast])
|
|
if pow2 then
|
|
from
|
|
np := n.item
|
|
until
|
|
not pow2 or np_offset >= nlast
|
|
loop
|
|
if np [np_offset] /= 0 then
|
|
pow2 := False
|
|
end
|
|
np_offset := np_offset + 1
|
|
end
|
|
end
|
|
count := leading_zeros (np [nlast])
|
|
nbits := size * limb_bits - (count) - pow2.to_integer
|
|
if nbits = 0 then
|
|
target.count := 0
|
|
else
|
|
np := n.item
|
|
np_offset := 0
|
|
rp := target.item
|
|
rp_offset := 0
|
|
if np = rp then
|
|
overlap := True
|
|
create np.make_filled (0, size)
|
|
np.copy_data (n.item, 0, 0, size)
|
|
end
|
|
target.resize (size)
|
|
rp := target.item
|
|
rp [rp_offset + size - 1] := 0
|
|
count := 80
|
|
from
|
|
cmp_l := 0
|
|
until
|
|
cmp_l < 0 or count = 0
|
|
loop
|
|
state.randget (rp, rp_offset, nbits)
|
|
cmp_l := cmp (rp, rp_offset, np, np_offset, size)
|
|
count := count - 1
|
|
end
|
|
if count = 0 then
|
|
sub_n (rp, rp_offset, rp, rp_offset, np, np_offset, size, carry)
|
|
junk := carry.item
|
|
end
|
|
size := normalize (rp, rp_offset, size)
|
|
target.count := size
|
|
end
|
|
end
|
|
end
|