<div dir="ltr">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.<div>
<br></div><div><div>;ms = "max sig fig count", rs = "rand sig fig count"</div><div>(define (random-integer ms [return-len? #f])</div><div>  (let ([rs (add1 (random ms))])</div><div>    (let R ([i rs] [sum 0])</div>
<div>      (if (zero? i)</div><div>          (if return-len? (values sum rs) sum)</div><div>          (R (sub1 i)</div><div>             (+ (* 10 sum) (random 10)))))))</div><div><br></div><div>(define (random-fraction ms)</div>
<div>  (let-values ([(frac-digits len) (random-integer ms #t)])</div><div>    (/ frac-digits (expt 10 len))))</div><div><br></div><div>(define (random-rational ms)</div><div>  (let* ([int-figs (random (add1 ms))]</div><div>
         [int (if (zero? int-figs)</div><div>                  0</div><div>                  (random-integer int-figs))]</div><div>         [frac-figs (- ms int-figs)]</div><div>         [frac (if (zero? frac-figs)</div><div>
                   0</div><div>                   (random-fraction frac-figs))])</div><div>    (+ int frac)))</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, May 17, 2014 at 12:39 AM, Neil Toronto <span dir="ltr"><<a href="mailto:neil.toronto@gmail.com" target="_blank">neil.toronto@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There's a random-real generator in "math/private/utils/flonum-<u></u>tests.rkt". The generator Typed Racket uses is in "tests/typed-racket/random-<u></u>real.rkt".<br>

<br>
I haven't settled on a general-purpose real number generator. For flonums I usually write something like this:<br>
<br>
#lang racket<br>
<br>
(require math/base math/flonum)<br>
<br>
(define max-ord (flonum->ordinal +max.0))<br>
<br>
(define (random-flonum)<br>
  (define r (random))<br>
  (cond [(< r 0.025)  +nan.0]<br>
        [(< r 0.050)  +inf.0]<br>
        [(< r 0.075)  -inf.0]<br>
        [(< r 0.100)  -0.0]<br>
        [(< r 0.125)  +0.0]<br>
        [else  (ordinal->flonum (random-integer (- max-ord)<br>
                                                (+ max-ord 1)))]))<br>
<br>
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.<br>
<br>
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?<span class="HOEnZb"><font color="#888888"><br>

<br>
Neil ⊥</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On 05/13/2014 11:46 AM, Robby Findler wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Okay, then I'll go with this:<br>
<br>
(define/contract (angle->proper-range α)<br>
   (-> real? (between/c 0 360))<br>
   (let loop ([θ (- α (* 360 (floor (/ α 360))))])<br>
     (cond [(negative? θ) (+ θ 360)]<br>
           [(>= θ 360)    (- θ 360)]<br>
           [else θ])))<br>
<br>
Can you point me to your random real number generator, btw?<br>
<br>
Robby<br>
<br>
<br>
On Tue, May 13, 2014 at 9:06 AM, Neil Toronto <<a href="mailto:neil.toronto@gmail.com" target="_blank">neil.toronto@gmail.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I can't get it to take more than on iteration, either. It's there in case I<br>
missed something. :)<br>
<br>
Neil ⊥<br>
<br>
<br>
On 05/13/2014 05:59 AM, Robby Findler wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Thanks, Neil!<br>
<br>
Why is the loop needed? I can't seem to get it to take more than one<br>
iteration.<br>
<br>
Robby<br>
<br>
On Mon, May 12, 2014 at 11:24 PM, Neil Toronto <<a href="mailto:neil.toronto@gmail.com" target="_blank">neil.toronto@gmail.com</a>><br>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
He went with exact rationals. Here's another option, which preserves<br>
inexactness:<br>
<br>
      (define (angle->proper-range α)<br>
        (let loop ([θ  (- α (* 360 (floor (/ α 360))))])<br>
          (cond [(negative? θ)  (loop (+ θ 360))]<br>
                [(>= θ 360)     (loop (- θ 360))]<br>
                [else  θ])))<br>
<br>
Its accuracy drops off outside of about [-1e16,1e16].<br>
<br>
The fact that this is hard to get right might be good motivation for an<br>
`flmodulo` function.<br>
<br>
Neil ⊥<br>
<br>
<br>
On 05/12/2014 09:49 PM, Sean Kanaley wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Interesting, my code has the same bug then.  I called it modulo/real,<br>
used for things like displaying the space ship's rotation to the user or<br>
wrapping x coordinates to stay in the world.  Apparently it's going to<br>
fail at some point with vector ref out of range.  What was your fix?  I<br>
was thinking to just clamp explicitly like mod/real = (max 0 (min<br>
the-mod-minus-1 (old-modulo/real x)))<br>
<br>
<br>
On Mon, May 12, 2014 at 11:12 PM, Robby Findler<br>
<<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a> <mailto:<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.<u></u>northwestern.edu</a>>><br>
wrote:<br>
<br>
      Right. Probably there is a better fix, but the essential problem,<br>
as I<br>
      understand it, is that there are more floating points between 0 and<br>
1<br>
      than between any two other integers and the code made the<br>
assumption<br>
      that that didn't happen....<br>
<br>
      The basic desire is to turn a real number into a number in [0,360)<br>
      such that the result represents the same number in degrees but is<br>
      normalized somehow.<br>
<br>
      Robby<br>
<br>
      On Mon, May 12, 2014 at 10:06 PM, Danny Yoo <<a href="mailto:dyoo@hashcollision.org" target="_blank">dyoo@hashcollision.org</a><br>
      <mailto:<a href="mailto:dyoo@hashcollision.org" target="_blank">dyoo@hashcollision.org</a><u></u>>> wrote:<br>
       > Wow.  Floating point really is nasty.  I see how it might have<br>
      happened now.<br>
       ><br>
       > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<u></u>;;;;;;;;;;;;;<br>
       >> -0.0000000000000001<br>
       > -1e-16<br>
       >> (+ 360 -1e-16)<br>
       > 360.0<br>
       >><br>
       > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<u></u>;;;;;;;;;;;;;<br>
<br>
<br>
<br>
<br>
____________________<br>
     Racket Users list:<br>
     <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/<u></u>users</a><br>
<br>
</blockquote>
<br>
____________________<br>
   Racket Users list:<br>
   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/<u></u>users</a><br>
</blockquote></blockquote>
<br>
<br>
</blockquote></blockquote>
<br>
____________________<br>
 Racket Users list:<br>
 <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/<u></u>users</a><br>
</div></div></blockquote></div><br></div>