@@ -148,21 +148,17 @@ rand{T<:Number}(::Type{T}, dims::Int...) = rand(T, dims)
148
148
149
149
# # Generate random integer within a range 1:n
150
150
151
- # remainder function according to Knuth, where rem_knuth(a, 0) = a
152
- rem_knuth (a:: Uint , b:: Uint ) = a % (b + (b == 0 )) + a * (b == 0 )
153
- rem_knuth {T<:Unsigned} (a:: T , b:: T ) = b != 0 ? a % b : a
154
-
155
- # maximum multiple of k <= 2^bits(T) decremented by one,
156
- # that is 0xFFFFFFFF if k = typemax(T) - typemin(T) with intentional underflow
157
- maxmultiple (k:: Uint32 ) = itrunc (Uint32, div (0x0000000100000000 ,k + (k == 0 ))* k - 1 )
158
- maxmultiple (k:: Uint64 ) = itrunc (Uint64, div (0x00000000000000010000000000000000 , k + (k == 0 ))* k - 1 )
159
- # maximum multiple of k within 1:typemax(Uint128)
160
- maxmultiple (k:: Uint128 ) = div (typemax (Uint128), k + (k == 0 ))* k - 1
161
- # maximum multiple of k within 1:2^32 or 1:2^64, depending on size
162
- maxmultiplemix (k:: Uint64 ) = itrunc (Uint64, div ((k >> 32 != 0 )* 0x0000000000000000FFFFFFFF00000000 + 0x0000000100000000 , k + (k == 0 ))* k - 1 )
151
+ # maxmultiple: precondition: k>0
152
+ # maximum multiple of k <= 2^numbits(k), decremented by one
153
+ maxmultiple (k:: Uint32 ) = itrunc (Uint32, div (0x0000000100000000 , k)* k - 1 )
154
+ maxmultiple (k:: Uint64 ) = itrunc (Uint64, div (0x00000000000000010000000000000000 , k)* k - 1 )
155
+ # maximum multiple of k <= typemax(Uint128), decremented by one
156
+ maxmultiple (k:: Uint128 ) = div (typemax (Uint128), k)* k - 1
157
+ # 32 or 64 bits version depending on size
158
+ maxmultiplemix (k:: Uint64 ) = k >> 32 == 0 ? uint64 (maxmultiple (itrunc (Uint32, k))) : maxmultiple (k)
163
159
164
160
immutable RandIntGen{T<: Integer , U<: Unsigned }
165
- k:: U # range length (or zero for full range)
161
+ k:: U # range length
166
162
u:: U # rejection threshold
167
163
end
168
164
# generators with 32, 128 bits entropy
@@ -179,7 +175,7 @@ for (T, U) in [(Uint8, Uint32), (Uint16, Uint32),
179
175
(Int8, Uint32), (Int16, Uint32), (Int32, Uint32), (Int64, Uint64), (Int128, Uint128),
180
176
(Bool, Uint32), (Char, Uint32)]
181
177
182
- @eval randintgen (k:: $T ) = k< 1 ? error (" range must be non-empty" ) : RandIntGen ($ T, convert ($ U, k)) # overflow ok
178
+ @eval randintgen (k:: $T ) = k< 1 ? error (" range must be non-empty" ) : RandIntGen ($ T, convert ($ U, k))
183
179
end
184
180
185
181
# this function uses 32 bit entropy for small ranges of length <= typemax(Uint32) + 1
@@ -197,15 +193,15 @@ function rand{T<:Union(Uint64, Int64)}(g::RandIntGen{T,Uint64})
197
193
x = rand (Uint64)
198
194
end
199
195
end
200
- return reinterpret (T, one (Uint64) + rem_knuth (x, g. k) )
196
+ return reinterpret (T, one (Uint64) + x % g. k)
201
197
end
202
198
203
199
function rand {T<:Integer, U<:Unsigned} (g:: RandIntGen{T,U} )
204
200
x = rand (U)
205
201
while x > g. u
206
202
x = rand (U)
207
203
end
208
- itrunc (T, one (U) + rem_knuth (x, g. k) )
204
+ itrunc (T, one (U) + x % g. k)
209
205
end
210
206
211
207
0 commit comments