What's wrong with the user parameterizing it like this? To save you from having to read the whole thing, it randomly makes digits that belong to either the integer or fractional portion where the user chooses the max number of digits to generate.
;ms = "max sig fig count", rs = "rand sig fig count" (define (random-integer ms [return-len? #f]) (let ([rs (add1 (random ms))]) (let R ([i rs] [sum 0]) (if (zero? i) (if return-len? (values sum rs) sum) (R (sub1 i) (+ (* 10 sum) (random 10))))))) (define (random-fraction ms) (let-values ([(frac-digits len) (random-integer ms #t)]) (/ frac-digits (expt 10 len)))) (define (random-rational ms) (let* ([int-figs (random (add1 ms))] [int (if (zero? int-figs) 0 (random-integer int-figs))] [frac-figs (- ms int-figs)] [frac (if (zero? frac-figs) 0 (random-fraction frac-figs))]) (+ int frac))) On Sat, May 17, 2014 at 12:39 AM, Neil Toronto <neil.toro...@gmail.com>wrote: > There's a random-real generator in "math/private/utils/flonum-tests.rkt". > The generator Typed Racket uses is in "tests/typed-racket/random- > real.rkt". > > I haven't settled on a general-purpose real number generator. For flonums > I usually write something like this: > > #lang racket > > (require math/base math/flonum) > > (define max-ord (flonum->ordinal +max.0)) > > (define (random-flonum) > (define r (random)) > (cond [(< r 0.025) +nan.0] > [(< r 0.050) +inf.0] > [(< r 0.075) -inf.0] > [(< r 0.100) -0.0] > [(< r 0.125) +0.0] > [else (ordinal->flonum (random-integer (- max-ord) > (+ max-ord 1)))])) > > Sometimes I have cases for -max.0, -min.0, +min.0 and +max.0 to test > near-underflow and near-overflow conditions, or a (- (random) 0.5) or > similar case to test more typical inputs. > > Rationals are a trickier because they're unbounded in both size and > precision. Probabilistically, they're a weird domain: a uniform probability > distribution over any given interval of rationals doesn't exist. You can > get around this by using a fixed precision, but what would you fix it at? > > Neil ⊥ > > > On 05/13/2014 11:46 AM, Robby Findler wrote: > >> Okay, then I'll go with this: >> >> (define/contract (angle->proper-range α) >> (-> real? (between/c 0 360)) >> (let loop ([θ (- α (* 360 (floor (/ α 360))))]) >> (cond [(negative? θ) (+ θ 360)] >> [(>= θ 360) (- θ 360)] >> [else θ]))) >> >> Can you point me to your random real number generator, btw? >> >> Robby >> >> >> On Tue, May 13, 2014 at 9:06 AM, Neil Toronto <neil.toro...@gmail.com> >> wrote: >> >>> I can't get it to take more than on iteration, either. It's there in >>> case I >>> missed something. :) >>> >>> Neil ⊥ >>> >>> >>> On 05/13/2014 05:59 AM, Robby Findler wrote: >>> >>>> >>>> Thanks, Neil! >>>> >>>> Why is the loop needed? I can't seem to get it to take more than one >>>> iteration. >>>> >>>> Robby >>>> >>>> On Mon, May 12, 2014 at 11:24 PM, Neil Toronto <neil.toro...@gmail.com> >>>> wrote: >>>> >>>>> >>>>> He went with exact rationals. Here's another option, which preserves >>>>> inexactness: >>>>> >>>>> (define (angle->proper-range α) >>>>> (let loop ([θ (- α (* 360 (floor (/ α 360))))]) >>>>> (cond [(negative? θ) (loop (+ θ 360))] >>>>> [(>= θ 360) (loop (- θ 360))] >>>>> [else θ]))) >>>>> >>>>> Its accuracy drops off outside of about [-1e16,1e16]. >>>>> >>>>> The fact that this is hard to get right might be good motivation for an >>>>> `flmodulo` function. >>>>> >>>>> Neil ⊥ >>>>> >>>>> >>>>> On 05/12/2014 09:49 PM, Sean Kanaley wrote: >>>>> >>>>>> >>>>>> >>>>>> Interesting, my code has the same bug then. I called it modulo/real, >>>>>> used for things like displaying the space ship's rotation to the user >>>>>> or >>>>>> wrapping x coordinates to stay in the world. Apparently it's going to >>>>>> fail at some point with vector ref out of range. What was your fix? >>>>>> I >>>>>> was thinking to just clamp explicitly like mod/real = (max 0 (min >>>>>> the-mod-minus-1 (old-modulo/real x))) >>>>>> >>>>>> >>>>>> On Mon, May 12, 2014 at 11:12 PM, Robby Findler >>>>>> <ro...@eecs.northwestern.edu <mailto:ro...@eecs.northwestern.edu>> >>>>>> wrote: >>>>>> >>>>>> Right. Probably there is a better fix, but the essential >>>>>> problem, >>>>>> as I >>>>>> understand it, is that there are more floating points between 0 >>>>>> and >>>>>> 1 >>>>>> than between any two other integers and the code made the >>>>>> assumption >>>>>> that that didn't happen.... >>>>>> >>>>>> The basic desire is to turn a real number into a number in >>>>>> [0,360) >>>>>> such that the result represents the same number in degrees but >>>>>> is >>>>>> normalized somehow. >>>>>> >>>>>> Robby >>>>>> >>>>>> On Mon, May 12, 2014 at 10:06 PM, Danny Yoo < >>>>>> d...@hashcollision.org >>>>>> <mailto:d...@hashcollision.org>> wrote: >>>>>> > Wow. Floating point really is nasty. I see how it might >>>>>> have >>>>>> happened now. >>>>>> > >>>>>> > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>>>> >> -0.0000000000000001 >>>>>> > -1e-16 >>>>>> >> (+ 360 -1e-16) >>>>>> > 360.0 >>>>>> >> >>>>>> > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>>>> >>>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>>> >>>> >>> >>> > ____________________ > Racket Users list: > http://lists.racket-lang.org/users >
____________________ Racket Users list: http://lists.racket-lang.org/users