[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

miscellaneous request (last one)



and finally (I promise), as it's occasionally convenient
to arithmetically propagate the sign of a value, how about:

(define (-/+ n) (/ n (+ n))) ; 1 * sign of n, where 0 -> 0

assuming (/ 0 0) => 0, and (+ n) :: (abs n), and although defined
using /, may likely be implemented as a primitive more efficiently.

then merged with earlier 2-cent thoughts:

; where div and quo naming may be swapped if preferred:
; n/d :: (+ (div n d) (r/d n d)) ; symmetric about 0
; n/d :: (+ (quo n d) (m/d n d)) ; asymmetric about 0
;  n  :: (+ (mod n d) (* (quo n d) d))

; where if (* 0 NaN) => 0 and (/ 0) => NaN
; then (/ 0 0) must => 0, to be consistent.

(define (/: n d) ; for NaN vs. div/0 error.
  (cond ((= n 0) 0) ((= d 0) +nan.0) (else (/ n d))))

(define (+: n) (abs n)) ; for (+ n) :: (abs n).

(define (-/+ n) (/: n (+: n))) ; 1 * sign of n, where 0 -> 0

; thereby:
; (div 0 x) =>  0  (quo 0 x) =>  0
; (rem 0 x) =>  0  (mod 0 x) =>  0
; (r/d 0 x) =>  0  (m/d 0 x) =>  0

; otherwise:
; (div x 0) => NaN (quo x 0) => NaN
; (rem x 0) =>  0  (mod x 0) =>  x
; (r/d x 0) =>  0  (m/d x 0) => NaN

;---

(define (div n d) ; symmetric about 0
  (truncate (/: n d)))

(define (rem n d) ; same sign as (div n d)
 (* (-/+ d) (- n (* (div n d) d))))

(define (r/d n d) ; remainder fraction
  (/: (rem n d) (+: d)))

; n/d :: (+ (div n d) (r/d n d))

;---

(define (quo n d) ; asymmetric about 0
  (floor (/: n d)))

(define (mod n d) ; same sign as d
  (- n (* (quo n d) d)))

(define (m/d n d) ; modular fraction
  (/: (mod n d) d))

; n/d :: (+ (quo n d) (m/d n d))
;  n  :: (+ (mod n d) (* (quo n d) d))

;---