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

Reply via email to