开发者

How do I do a floating-point modulo operation in Scheme?

% isn't defined. modulo only works on integers. I want something equivalent to Java开发者_StackOverflow社区script's modulo / c's fmod.


I don't know scheme, but mathematically you could do something like:

rem = num - trunc(num / mod) * mod;

So for a number like 2.5 mod 2 you would get:

2.5 - trunc(2.5 / 2) * 2
= 2.5 - trunc(1.25) * 2
= 2.5 - 1 * 2
= 2.5 - 2
= 0.5


Here is the javascript equivalent, I believe, where n=dividend, d=divisor:

(let ((nOverD (/ n d)))
      (let ((q (if (> nOverD 0.0) (floor nOverD) (ceiling nOverD))))
        (- n (* d q))))


The flonum library defines flmod, which does what you want. In Pilot Scheme:

(require rnrs/arithmetic/flonums-6)
(flmod pi (sqrt 2))


If your goal is to normalize angle to fit between -π and π, then you can do it like this:

(angle (make-polar 1 x))

Otherwise, you can scale your arguments:

(define (mod* x y)
  (let* ((pi (* 4 (atan 1)))
         (c (/ y pi))
         (result (angle (make-polar 1 (/ x c)))))
    (* (+ result (if (negative? result) pi 0)) c)))

I'm not sure how the function should behave for negative arguments, so I didn't consider them.


The mod function seems to take integers, rationals and floating point numbers (e.g. in petite chez scheme):

> (mod 10 4.5)
1.0
> (mod 5.5 1.4)
1.3000000000000007
> (mod 5.5 2/3)
0.16666666666666696

If you want operations that only take a floating point number, called a "flonum" in scheme and you're using a r6rs compliant scheme, there are a bunch of flonum operations defined in the library, including flmod, e.g.:

> (flmod 5. 4.)
1.0
> (flmod 5. 4.5)
0.5
> (flmod 10. 4.5)
1.0
> (flmod 10 4.5)
Exception in flmod: 10 is not a flonum

The above was run in chez scheme.

For flonum operations, see section 11.3 on page 46 of [1]

[1] http://www.r6rs.org/final/r6rs-lib.pdf


It looks like remainder is the word you want. From here:

(remainder -13 -4.0)      -1.0
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜