177 | 177 |
[value]
|
178 | 178 |
(rose/make-rose value (core/map int-rose-tree (shrink-int value))))
|
179 | 179 |
|
|
180 |
;; calc-long is factored out to support testing the surprisingly tricky double math. Note:
|
|
181 |
;; An extreme long value does not have a precision-preserving representation as a double.
|
|
182 |
;; Be careful about changing this code unless you understand what's happening in these
|
|
183 |
;; examples:
|
|
184 |
;;
|
|
185 |
;; (= (long (- Integer/MAX_VALUE (double (- Integer/MAX_VALUE 10)))) 10)
|
|
186 |
;; (= (long (- Long/MAX_VALUE (double (- Long/MAX_VALUE 10)))) 0)
|
|
187 |
|
|
188 |
(defn- calc-long
|
|
189 |
[factor lower upper]
|
|
190 |
;; these pre- and post-conditions are disabled for deployment
|
|
191 |
#_ {:pre [(float? factor) (>= factor 0.0) (< factor 1.0)
|
|
192 |
(integer? lower) (integer? upper) (<= lower upper)]
|
|
193 |
:post [(integer? %)]}
|
|
194 |
;; Use -' on width to maintain accuracy with overflow protection.
|
|
195 |
(let [width (-' upper lower -1)]
|
|
196 |
;; Preserve long precision if the width is in the long range. Otherwise, we must accept
|
|
197 |
;; less precision because doubles don't have enough bits to preserve long equivalence at
|
|
198 |
;; extreme values.
|
|
199 |
(if (< width Long/MAX_VALUE)
|
|
200 |
(+ lower (long (Math/floor (* factor width))))
|
|
201 |
;; Clamp down to upper because double math.
|
|
202 |
(min upper (long (Math/floor (+ lower (* factor width))))))))
|
|
203 |
|
180 | 204 |
(defn- rand-range
|
181 | 205 |
[rnd lower upper]
|
182 | 206 |
{:pre [(<= lower upper)]}
|
183 | |
(let [factor (random/rand-double rnd)
|
184 | |
;; Use -' to maintain accuracy with overflow protection.
|
185 | |
width (-' upper lower -1)]
|
186 | |
(if (< width Long/MAX_VALUE)
|
187 | |
(long (+ lower (Math/floor (* factor width))))
|
188 | |
;; Clamp down to upper because double math.
|
189 | |
(long (min upper (Math/floor (+ lower (* factor width))))))))
|
|
207 |
(calc-long (random/rand-double rnd) lower upper))
|
190 | 208 |
|
191 | 209 |
(defn sized
|
192 | 210 |
"Create a generator that depends on the size parameter.
|
|
218 | 236 |
(sized (fn [n] (resize (f n) generator)))))
|
219 | 237 |
|
220 | 238 |
(defn choose
|
221 | |
"Create a generator that returns numbers in the range
|
222 | |
`min-range` to `max-range`, inclusive."
|
|
239 |
"Create a generator that returns long integers in the range `lower` to `upper`, inclusive."
|
223 | 240 |
[lower upper]
|
224 | |
(make-gen
|
225 | |
(fn [rnd _size]
|
226 | |
(let [value (rand-range rnd lower upper)]
|
227 | |
(rose/filter
|
|
241 |
;; cast to long to support doubles as arguments per TCHECK-73
|
|
242 |
(let [lower (long lower)
|
|
243 |
upper (long upper)]
|
|
244 |
(make-gen
|
|
245 |
(fn [rnd _size]
|
|
246 |
(let [value (rand-range rnd lower upper)]
|
|
247 |
(rose/filter
|
228 | 248 |
#(and (>= % lower) (<= % upper))
|
229 | |
(int-rose-tree value))))))
|
|
249 |
(int-rose-tree value)))))))
|
230 | 250 |
|
231 | 251 |
(defn one-of
|
232 | 252 |
"Create a generator that randomly chooses a value from the list of
|