2007-10-25 16:27:34 -04:00
|
|
|
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
|
2008-01-29 00:34:34 -05:00
|
|
|
;;; Copyright (C) 2006,2007,2008 Abdulaziz Ghuloum
|
2007-10-25 16:27:34 -04:00
|
|
|
;;;
|
|
|
|
;;; This program is free software: you can redistribute it and/or modify
|
|
|
|
;;; it under the terms of the GNU General Public License version 3 as
|
|
|
|
;;; published by the Free Software Foundation.
|
|
|
|
;;;
|
|
|
|
;;; This program is distributed in the hope that it will be useful, but
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
;;; General Public License for more details.
|
|
|
|
;;;
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2007-05-05 03:01:12 -04:00
|
|
|
(library (ikarus flonums)
|
2008-07-24 21:58:53 -04:00
|
|
|
(export $flonum->exact flonum-parts
|
2007-08-28 18:15:27 -04:00
|
|
|
inexact->exact exact $flonum-rational? $flonum-integer? $flzero?
|
2007-09-02 21:16:54 -04:00
|
|
|
$flnegative? flpositive? flabs fixnum->flonum
|
2007-09-10 22:45:41 -04:00
|
|
|
flsin flcos fltan flasin flacos flatan fleven? flodd?
|
2007-09-11 00:13:10 -04:00
|
|
|
flfloor flceiling flnumerator fldenominator flexp fllog
|
2007-09-12 03:56:08 -04:00
|
|
|
flinteger? flonum-bytes flnan? flfinite? flinfinite?
|
2007-11-17 02:13:44 -05:00
|
|
|
flexpt $flround flround)
|
2007-05-05 03:01:12 -04:00
|
|
|
(import
|
2007-05-18 21:52:04 -04:00
|
|
|
(ikarus system $bytevectors)
|
2007-09-10 22:45:41 -04:00
|
|
|
(ikarus system $fx)
|
2007-11-14 17:24:29 -05:00
|
|
|
(only (ikarus system $flonums) $fl>= $flonum-sbe)
|
2007-09-10 22:45:41 -04:00
|
|
|
(ikarus system $bignums)
|
2007-11-17 02:13:44 -05:00
|
|
|
(except (ikarus system $flonums) $flonum-rational?
|
|
|
|
$flonum-integer? $flround)
|
2007-09-10 22:45:41 -04:00
|
|
|
(except (ikarus) inexact->exact exact flpositive? flabs fixnum->flonum
|
|
|
|
flsin flcos fltan flasin flacos flatan fleven? flodd?
|
2007-09-11 00:13:10 -04:00
|
|
|
flfloor flceiling flnumerator fldenominator flexp fllog
|
2007-09-12 03:56:08 -04:00
|
|
|
flexpt flinteger? flonum-parts flonum-bytes flnan? flfinite?
|
2007-11-17 02:13:44 -05:00
|
|
|
flinfinite? flround))
|
2007-06-10 00:32:19 -04:00
|
|
|
|
|
|
|
(define (flonum-bytes f)
|
|
|
|
(unless (flonum? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flonum-bytes "not a flonum" f))
|
2007-06-10 00:32:19 -04:00
|
|
|
(values
|
|
|
|
($flonum-u8-ref f 0)
|
|
|
|
($flonum-u8-ref f 1)
|
|
|
|
($flonum-u8-ref f 2)
|
|
|
|
($flonum-u8-ref f 3)
|
|
|
|
($flonum-u8-ref f 4)
|
|
|
|
($flonum-u8-ref f 5)
|
|
|
|
($flonum-u8-ref f 6)
|
|
|
|
($flonum-u8-ref f 7)))
|
|
|
|
(define (flonum-parts x)
|
|
|
|
(unless (flonum? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flonum-parts "not a flonum" x))
|
2007-06-10 00:32:19 -04:00
|
|
|
(let-values ([(b0 b1 b2 b3 b4 b5 b6 b7) (flonum-bytes x)])
|
|
|
|
(values
|
|
|
|
(zero? (fxlogand b0 128))
|
|
|
|
(+ (fxsll (fxlogand b0 127) 4)
|
|
|
|
(fxsra b1 4))
|
|
|
|
(+ (+ b7 (fxsll b6 8) (fxsll b5 16))
|
|
|
|
(* (+ b4
|
|
|
|
(fxsll b3 8)
|
|
|
|
(fxsll b2 16)
|
|
|
|
(fxsll (fxlogand b1 #b1111) 24))
|
|
|
|
(expt 2 24))))))
|
2007-09-10 22:10:19 -04:00
|
|
|
(define ($zero-m? f)
|
|
|
|
(and ($fxzero? ($flonum-u8-ref f 7))
|
|
|
|
($fxzero? ($flonum-u8-ref f 6))
|
|
|
|
($fxzero? ($flonum-u8-ref f 5))
|
|
|
|
($fxzero? ($flonum-u8-ref f 4))
|
|
|
|
($fxzero? ($flonum-u8-ref f 3))
|
|
|
|
($fxzero? ($flonum-u8-ref f 2))
|
|
|
|
($fxzero? ($fxlogand ($flonum-u8-ref f 1) #b1111))))
|
|
|
|
|
2007-06-13 02:03:30 -04:00
|
|
|
(define ($flonum-rational? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be ($fxlogand ($flonum-sbe x)
|
2007-11-11 16:48:03 -05:00
|
|
|
($fxsub1 ($fxsll 1 11)))])
|
|
|
|
($fx< be 2047)))
|
2007-06-13 02:03:30 -04:00
|
|
|
|
|
|
|
(define ($flonum-integer? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be ($fxlogand ($flonum-sbe x)
|
2007-11-11 16:48:03 -05:00
|
|
|
($fxsub1 ($fxsll 1 11)))])
|
2007-06-13 02:03:30 -04:00
|
|
|
(cond
|
2007-11-11 16:48:03 -05:00
|
|
|
[($fx= be 2047) ;;; nans and infs
|
2007-06-13 02:03:30 -04:00
|
|
|
#f]
|
2007-11-11 16:48:03 -05:00
|
|
|
[($fx>= be 1075) ;;; magnitue large enough
|
2007-06-13 02:03:30 -04:00
|
|
|
#t]
|
2007-11-11 16:48:03 -05:00
|
|
|
[($fx= be 0) ;;; denormalized double, only +/-0.0 is integer
|
|
|
|
(and ($fx= ($flonum-u8-ref x 7) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 6) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 5) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 4) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 3) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 2) 0)
|
|
|
|
($fx= ($flonum-u8-ref x 1) 0))]
|
|
|
|
[($fx< be ($fx+ 1075 -52)) ;;; too small to be an integer
|
2007-06-13 02:03:30 -04:00
|
|
|
#f]
|
2007-11-14 18:45:49 -05:00
|
|
|
[else ($fl= x ($flround x))])))
|
|
|
|
|
2007-11-17 02:13:44 -05:00
|
|
|
|
|
|
|
(define ($flround x)
|
|
|
|
(foreign-call "ikrt_fl_round" x ($make-flonum)))
|
|
|
|
|
|
|
|
(define (flround x)
|
|
|
|
(if (flonum? x)
|
|
|
|
($flround x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flround "not a flonum" x)))
|
2007-11-17 02:13:44 -05:00
|
|
|
|
2008-07-24 21:58:53 -04:00
|
|
|
(module ($flonum->exact)
|
2007-11-14 18:45:49 -05:00
|
|
|
(define ($flonum-signed-mantissa x)
|
|
|
|
(let ([b0 ($flonum-u8-ref x 0)])
|
|
|
|
(let ([m0 ($fx+ ($flonum-u8-ref x 7)
|
|
|
|
($fx+ ($fxsll ($flonum-u8-ref x 6) 8)
|
|
|
|
($fxsll ($flonum-u8-ref x 5) 16)))]
|
|
|
|
[m1 ($fx+ ($flonum-u8-ref x 4)
|
|
|
|
($fx+ ($fxsll ($flonum-u8-ref x 3) 8)
|
|
|
|
($fxsll ($flonum-u8-ref x 2) 16)))]
|
|
|
|
[m2 (let ([b1 ($flonum-u8-ref x 1)])
|
|
|
|
(if (and ($fx= ($fxlogand b0 #x7F) 0)
|
|
|
|
($fx= ($fxsra b1 4) 0))
|
|
|
|
($fxlogand b1 #xF)
|
|
|
|
($fxlogor ($fxlogand b1 #xF) #x10)))])
|
|
|
|
(if ($fx= 0 ($fxlogand #x80 b0))
|
|
|
|
(+ (bitwise-arithmetic-shift-left ($fxlogor m1 ($fxsll m2 24)) 24) m0)
|
|
|
|
(+ (bitwise-arithmetic-shift-left
|
|
|
|
($fx- 0 ($fxlogor m1 ($fxsll m2 24))) 24)
|
|
|
|
($fx- 0 m0))))))
|
2007-11-14 20:45:37 -05:00
|
|
|
(define ($flonum->exact x)
|
2007-11-17 09:12:49 -05:00
|
|
|
(import (ikarus))
|
2007-11-14 20:45:37 -05:00
|
|
|
(let ([sbe ($flonum-sbe x)])
|
|
|
|
(let ([be ($fxlogand sbe #x7FF)])
|
|
|
|
(cond
|
|
|
|
[($fx= be 2047) #f] ;;; nans/infs
|
|
|
|
[($fx>= be 1075) ;;; magnitude large enough to be an integer
|
|
|
|
(bitwise-arithmetic-shift-left
|
|
|
|
($flonum-signed-mantissa x)
|
|
|
|
(- be 1075))]
|
|
|
|
[else
|
2007-11-17 02:13:44 -05:00
|
|
|
;;; this really needs to get optimized.
|
|
|
|
(let-values ([(pos? be m) (flonum-parts x)])
|
2007-11-14 20:45:37 -05:00
|
|
|
(cond
|
2007-11-17 09:12:49 -05:00
|
|
|
[(= be 0) ;;; denormalized
|
|
|
|
(if (= m 0)
|
|
|
|
0
|
|
|
|
(* (if pos? 1 -1)
|
2008-07-24 21:58:53 -04:00
|
|
|
(/ m (expt 2 1074))))]
|
2007-11-17 09:12:49 -05:00
|
|
|
[else ; normalized flonum
|
2008-07-24 21:58:53 -04:00
|
|
|
(/ (+ m (expt 2 52))
|
2007-11-17 09:12:49 -05:00
|
|
|
(bitwise-arithmetic-shift-left
|
|
|
|
(if pos? 1 -1)
|
|
|
|
(- 1075 be)))]))])))))
|
2007-06-13 02:03:30 -04:00
|
|
|
|
2007-09-10 23:30:17 -04:00
|
|
|
(define (flnumerator x)
|
|
|
|
(unless (flonum? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flnumerator "not a flonum" x))
|
2007-09-10 23:30:17 -04:00
|
|
|
(cond
|
|
|
|
[($flonum-integer? x) x]
|
|
|
|
[($flonum-rational? x)
|
|
|
|
(exact->inexact (numerator ($flonum->exact x)))]
|
|
|
|
[else x]))
|
|
|
|
|
|
|
|
(define (fldenominator x)
|
|
|
|
(unless (flonum? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'fldenominator "not a flonum" x))
|
2007-09-10 23:30:17 -04:00
|
|
|
(cond
|
|
|
|
[($flonum-integer? x) 1.0]
|
|
|
|
[($flonum-rational? x)
|
2007-09-11 02:06:26 -04:00
|
|
|
(exact->inexact (denominator ($flonum->exact x)))]
|
2007-09-10 23:30:17 -04:00
|
|
|
[(flnan? x) x]
|
|
|
|
[else 1.0]))
|
2007-09-10 22:45:41 -04:00
|
|
|
|
|
|
|
(define (fleven? x)
|
2007-11-14 18:45:49 -05:00
|
|
|
;;; FIXME: optimize
|
2007-09-10 22:45:41 -04:00
|
|
|
(unless (flonum? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'fleven? "not a flonum" x))
|
2007-09-10 22:45:41 -04:00
|
|
|
(let ([v ($flonum->exact x)])
|
|
|
|
(cond
|
|
|
|
[(fixnum? v) ($fx= ($fxlogand v 1) 0)]
|
|
|
|
[(bignum? v)
|
|
|
|
(foreign-call "ikrt_even_bn" v)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'fleven? "not an integer flonum" x)])))
|
2007-09-10 22:45:41 -04:00
|
|
|
|
|
|
|
(define (flodd? x)
|
|
|
|
(unless (flonum? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flodd? "not a flonum" x))
|
2007-11-14 18:45:49 -05:00
|
|
|
;;; FIXME: optimize
|
2007-09-10 22:45:41 -04:00
|
|
|
(let ([v ($flonum->exact x)])
|
|
|
|
(cond
|
|
|
|
[(fixnum? v) ($fx= ($fxlogand v 1) 1)]
|
|
|
|
[(bignum? v)
|
|
|
|
(not (foreign-call "ikrt_even_bn" v))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'flodd? "not an integer flonum" x)])))
|
2007-09-10 22:45:41 -04:00
|
|
|
|
2007-09-10 20:47:17 -04:00
|
|
|
(define (flinteger? x)
|
|
|
|
(if (flonum? x)
|
|
|
|
($flonum-integer? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flinteger? "not a flonum" x)))
|
2007-09-10 20:47:17 -04:00
|
|
|
|
2007-09-10 22:10:19 -04:00
|
|
|
(define (flinfinite? x)
|
|
|
|
(if (flonum? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be (fxlogand ($flonum-sbe x) (sub1 (fxsll 1 11)))])
|
2007-09-10 22:10:19 -04:00
|
|
|
(and (fx= be 2047) ;;; nans and infs
|
|
|
|
($zero-m? x)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flinfinite? "not a flonum" x)))
|
2007-09-10 20:47:17 -04:00
|
|
|
|
2007-09-10 22:10:19 -04:00
|
|
|
(define (flnan? x)
|
|
|
|
(if (flonum? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be (fxlogand ($flonum-sbe x) (sub1 (fxsll 1 11)))])
|
2007-09-10 22:10:19 -04:00
|
|
|
(and (fx= be 2047) ;;; nans and infs
|
|
|
|
(not ($zero-m? x))))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flnan? "not a flonum" x)))
|
2007-09-10 22:10:19 -04:00
|
|
|
|
|
|
|
(define (flfinite? x)
|
|
|
|
(if (flonum? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be (fxlogand ($flonum-sbe x) (sub1 (fxsll 1 11)))])
|
2007-09-10 22:10:19 -04:00
|
|
|
(not (fx= be 2047)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flfinite? "not a flonum" x)))
|
2007-09-10 22:10:19 -04:00
|
|
|
|
2007-06-13 07:08:12 -04:00
|
|
|
(define ($flzero? x)
|
2007-11-14 17:24:29 -05:00
|
|
|
(let ([be (fxlogand ($flonum-sbe x) (sub1 (fxsll 1 11)))])
|
2007-06-13 07:08:12 -04:00
|
|
|
(and
|
|
|
|
(fx= be 0) ;;; denormalized double, only +/-0.0 is integer
|
|
|
|
(and (fx= ($flonum-u8-ref x 7) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 6) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 5) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 4) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 3) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 2) 0)
|
|
|
|
(fx= ($flonum-u8-ref x 1) 0)))))
|
|
|
|
|
2007-06-13 07:11:39 -04:00
|
|
|
(define ($flnegative? x)
|
|
|
|
(let ([b0 ($flonum-u8-ref x 0)])
|
|
|
|
(fx> b0 127)))
|
|
|
|
|
2007-06-10 00:32:19 -04:00
|
|
|
|
2007-06-10 00:35:39 -04:00
|
|
|
|
2007-11-14 17:24:29 -05:00
|
|
|
|
|
|
|
|
2007-06-10 00:35:39 -04:00
|
|
|
(define (inexact->exact x)
|
|
|
|
(cond
|
|
|
|
[(flonum? x)
|
|
|
|
(or ($flonum->exact x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'inexact->exact "no real value" x))]
|
2007-06-10 00:35:39 -04:00
|
|
|
[(or (fixnum? x) (ratnum? x) (bignum? x)) x]
|
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'inexact->exact "not an inexact number" x)]))
|
2007-06-16 02:59:39 -04:00
|
|
|
|
2007-08-28 18:15:27 -04:00
|
|
|
(define (exact x)
|
|
|
|
(cond
|
|
|
|
[(flonum? x)
|
|
|
|
(or ($flonum->exact x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'exact "no real value" x))]
|
2007-08-28 18:15:27 -04:00
|
|
|
[(or (fixnum? x) (ratnum? x) (bignum? x)) x]
|
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'exact "not an inexact number" x)]))
|
2007-08-28 18:15:27 -04:00
|
|
|
|
|
|
|
|
2007-06-16 02:59:39 -04:00
|
|
|
(define (flpositive? x)
|
|
|
|
(if (flonum? x)
|
|
|
|
($fl> x 0.0)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flpositive? "not a flonum" x)))
|
2007-06-10 00:32:19 -04:00
|
|
|
|
2007-06-16 02:59:39 -04:00
|
|
|
(define (flabs x)
|
|
|
|
(if (flonum? x)
|
2007-11-08 13:16:26 -05:00
|
|
|
(if ($fx> ($flonum-u8-ref x 0) 127)
|
2007-06-17 10:20:19 -04:00
|
|
|
($fl* x -1.0)
|
2007-06-16 02:59:39 -04:00
|
|
|
x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flabs "not a flonum" x)))
|
2007-09-02 21:02:06 -04:00
|
|
|
|
|
|
|
(define (fixnum->flonum x)
|
|
|
|
(if (fixnum? x)
|
|
|
|
($fixnum->flonum x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'fixnum->flonum "not a fixnum")))
|
2007-09-02 21:02:06 -04:00
|
|
|
|
2007-09-02 21:16:54 -04:00
|
|
|
(define (flsin x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_sin" x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flsin "not a flonum" x)))
|
2007-09-02 21:16:54 -04:00
|
|
|
|
|
|
|
(define (flcos x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_cos" x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flcos "not a flonum" x)))
|
2007-09-02 21:16:54 -04:00
|
|
|
|
|
|
|
(define (fltan x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_tan" x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'fltan "not a flonum" x)))
|
2007-09-02 21:16:54 -04:00
|
|
|
|
|
|
|
(define (flasin x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_asin" x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flasin "not a flonum" x)))
|
2007-09-02 21:16:54 -04:00
|
|
|
|
|
|
|
(define (flacos x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_acos" x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flacos "not a flonum" x)))
|
2007-09-02 21:16:54 -04:00
|
|
|
|
2008-07-24 03:06:12 -04:00
|
|
|
(define flatan
|
|
|
|
(case-lambda
|
|
|
|
[(x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_atan" x)
|
|
|
|
(die 'flatan "not a flonum" x))]
|
|
|
|
[(x y)
|
|
|
|
(if (flonum? x)
|
|
|
|
(if (flonum? y)
|
|
|
|
(foreign-call "ikrt_atan2" x y)
|
|
|
|
(die 'flatan "not a flonum" y))
|
|
|
|
(die 'flatan "not a flonum" x))]))
|
2007-09-10 23:17:06 -04:00
|
|
|
|
|
|
|
(define (flfloor x)
|
|
|
|
(define (ratnum-floor x)
|
|
|
|
(let ([n (numerator x)] [d (denominator x)])
|
|
|
|
(let ([q (quotient n d)])
|
|
|
|
(if (>= n 0) q (- q 1)))))
|
|
|
|
(cond
|
|
|
|
[(flonum? x)
|
2007-11-14 18:45:49 -05:00
|
|
|
;;; optimize for integer flonums case
|
2007-09-10 23:17:06 -04:00
|
|
|
(let ([e ($flonum->exact x)])
|
|
|
|
(cond
|
|
|
|
[(ratnum? e)
|
|
|
|
(exact->inexact (ratnum-floor e))]
|
|
|
|
[else x]))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'flfloor "not a flonum" x)]))
|
2007-09-10 23:17:06 -04:00
|
|
|
|
|
|
|
(define (flceiling x)
|
|
|
|
(cond
|
|
|
|
[(flonum? x)
|
2007-11-14 18:45:49 -05:00
|
|
|
;;; optimize for integer flonums case
|
2007-09-10 23:17:06 -04:00
|
|
|
(let ([e ($flonum->exact x)])
|
|
|
|
(cond
|
|
|
|
[(ratnum? e)
|
|
|
|
(exact->inexact (ceiling e))]
|
|
|
|
[else x]))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'flceiling "not a flonum" x)]))
|
2007-09-10 23:17:06 -04:00
|
|
|
|
2007-09-10 23:36:36 -04:00
|
|
|
(define (flexp x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_exp" x ($make-flonum))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flexp "not a flonum" x)))
|
2007-09-10 23:36:36 -04:00
|
|
|
|
2008-08-04 19:44:24 -04:00
|
|
|
(define fllog
|
|
|
|
(case-lambda
|
|
|
|
[(x)
|
|
|
|
(if (flonum? x)
|
|
|
|
(foreign-call "ikrt_fl_log" x)
|
|
|
|
(die 'fllog "not a flonum" x))]
|
|
|
|
[(x y)
|
|
|
|
(if (flonum? x)
|
|
|
|
(if (flonum? y)
|
|
|
|
(fl/ (foreign-call "ikrt_fl_log" x)
|
|
|
|
(foreign-call "ikrt_fl_log" y))
|
|
|
|
(die 'fllog "not a flonum" y))
|
|
|
|
(die 'fllog "not a flonum" x))]))
|
2007-09-11 00:13:10 -04:00
|
|
|
|
2007-09-12 03:56:08 -04:00
|
|
|
(define (flexpt x y)
|
|
|
|
(if (flonum? x)
|
|
|
|
(if (flonum? y)
|
2007-11-04 10:24:08 -05:00
|
|
|
(let ([y^ ($flonum->exact y)])
|
|
|
|
;;; FIXME: performance bottleneck?
|
2007-09-12 03:56:08 -04:00
|
|
|
(cond
|
|
|
|
[(fixnum? y^) (inexact (expt x y^))]
|
|
|
|
[(bignum? y^) (inexact (expt x y^))]
|
|
|
|
[else
|
|
|
|
(foreign-call "ikrt_flfl_expt" x y ($make-flonum))]))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'flexpt "not a flonum" y))
|
|
|
|
(die 'fllog "not a flonum" x)))
|
2008-05-19 00:41:53 -04:00
|
|
|
)
|
2007-09-10 23:17:06 -04:00
|
|
|
|
|
|
|
|
2007-05-05 03:01:12 -04:00
|
|
|
(library (ikarus generic-arithmetic)
|
2007-05-20 23:23:54 -04:00
|
|
|
(export + - * / zero? = < <= > >= add1 sub1 quotient remainder
|
2008-05-18 05:27:55 -04:00
|
|
|
modulo even? odd? bitwise-and bitwise-not bitwise-ior
|
2008-08-05 02:43:11 -04:00
|
|
|
bitwise-xor bitwise-if
|
2007-11-08 20:57:11 -05:00
|
|
|
bitwise-arithmetic-shift-right bitwise-arithmetic-shift-left
|
|
|
|
bitwise-arithmetic-shift
|
2008-08-05 02:43:11 -04:00
|
|
|
bitwise-length bitwise-copy-bit-field
|
2008-01-20 23:13:24 -05:00
|
|
|
bitwise-copy-bit bitwise-bit-field
|
2007-12-23 17:33:13 -05:00
|
|
|
positive? negative? expt gcd lcm numerator denominator
|
|
|
|
exact-integer-sqrt
|
2008-05-31 23:10:17 -04:00
|
|
|
quotient+remainder number->string min max
|
2007-11-11 01:13:09 -05:00
|
|
|
abs truncate fltruncate sra sll real->flonum
|
2007-08-28 18:15:27 -04:00
|
|
|
exact->inexact inexact floor ceiling round log fl=? fl<? fl<=? fl>?
|
2007-06-13 11:17:21 -04:00
|
|
|
fl>=? fl+ fl- fl* fl/ flsqrt flmin flzero? flnegative?
|
2007-09-15 00:14:47 -04:00
|
|
|
sin cos tan asin acos atan sqrt exp
|
2008-08-12 04:17:04 -04:00
|
|
|
sinh cosh tanh asinh acosh atanh
|
2008-02-13 18:12:00 -05:00
|
|
|
flmax random
|
|
|
|
error@add1 error@sub1)
|
2007-05-05 03:01:12 -04:00
|
|
|
(import
|
2007-05-06 18:43:04 -04:00
|
|
|
(ikarus system $fx)
|
2007-06-10 13:21:41 -04:00
|
|
|
(ikarus system $flonums)
|
2007-05-20 23:23:54 -04:00
|
|
|
(ikarus system $ratnums)
|
|
|
|
(ikarus system $bignums)
|
2008-05-19 00:41:53 -04:00
|
|
|
(ikarus system $compnums)
|
2007-05-06 18:43:04 -04:00
|
|
|
(ikarus system $chars)
|
|
|
|
(ikarus system $strings)
|
2007-11-14 18:45:49 -05:00
|
|
|
(only (ikarus flonums) $flonum->exact $flzero? $flnegative?
|
2008-07-24 21:58:53 -04:00
|
|
|
$flround)
|
2007-05-20 23:23:54 -04:00
|
|
|
(except (ikarus) + - * / zero? = < <= > >= add1 sub1 quotient
|
2007-08-28 17:45:54 -04:00
|
|
|
remainder modulo even? odd? quotient+remainder number->string
|
2007-11-08 20:57:11 -05:00
|
|
|
bitwise-arithmetic-shift-right bitwise-arithmetic-shift-left
|
|
|
|
bitwise-arithmetic-shift
|
2008-08-05 02:43:11 -04:00
|
|
|
bitwise-length bitwise-copy-bit-field
|
2008-01-20 23:13:24 -05:00
|
|
|
bitwise-copy-bit bitwise-bit-field
|
2008-05-18 05:27:55 -04:00
|
|
|
positive? negative? bitwise-and bitwise-not bitwise-ior
|
2008-08-05 02:43:11 -04:00
|
|
|
bitwise-xor bitwise-if
|
2008-05-31 23:10:17 -04:00
|
|
|
expt gcd lcm numerator denominator
|
2007-08-28 18:15:27 -04:00
|
|
|
exact->inexact inexact floor ceiling round log
|
2007-11-11 01:13:09 -05:00
|
|
|
exact-integer-sqrt min max abs real->flonum
|
2007-06-13 07:16:03 -04:00
|
|
|
fl=? fl<? fl<=? fl>? fl>=? fl+ fl- fl* fl/ flsqrt flmin
|
2007-09-15 00:14:47 -04:00
|
|
|
flzero? flnegative? sra sll exp
|
2007-09-11 00:22:23 -04:00
|
|
|
sin cos tan asin acos atan sqrt truncate fltruncate
|
2008-08-12 04:17:04 -04:00
|
|
|
sinh cosh tanh asinh acosh atanh
|
2007-11-17 02:13:44 -05:00
|
|
|
flmax random))
|
2007-05-20 23:23:54 -04:00
|
|
|
|
2008-01-12 20:52:23 -05:00
|
|
|
(define (bignum->flonum x)
|
|
|
|
(foreign-call "ikrt_bignum_to_flonum" x 0 ($make-flonum)))
|
2007-11-13 00:45:04 -05:00
|
|
|
|
|
|
|
|
2007-11-17 02:13:44 -05:00
|
|
|
;;; (define (ratnum->flonum x)
|
|
|
|
;;; (define (->flonum n d)
|
|
|
|
;;; (let-values ([(q r) (quotient+remainder n d)])
|
|
|
|
;;; (if (= r 0)
|
|
|
|
;;; (inexact q)
|
|
|
|
;;; (if (= q 0)
|
|
|
|
;;; (/ (->flonum d n))
|
|
|
|
;;; (+ q (->flonum r d))))))
|
|
|
|
;;; (let ([n (numerator x)] [d (denominator x)])
|
|
|
|
;;; (let ([b (bitwise-first-bit-set n)])
|
|
|
|
;;; (if (eqv? b 0)
|
|
|
|
;;; (let ([b (bitwise-first-bit-set d)])
|
|
|
|
;;; (if (eqv? b 0)
|
|
|
|
;;; (->flonum n d)
|
|
|
|
;;; (/ (->flonum n (bitwise-arithmetic-shift-right d b))
|
|
|
|
;;; (expt 2.0 b))))
|
|
|
|
;;; (* (->flonum (bitwise-arithmetic-shift-right n b) d)
|
|
|
|
;;; (expt 2.0 b))))))
|
2008-01-06 02:27:23 -05:00
|
|
|
|
|
|
|
;;; (define (ratnum->flonum x)
|
|
|
|
;;; (let f ([n ($ratnum-n x)] [d ($ratnum-d x)])
|
|
|
|
;;; (let-values ([(q r) (quotient+remainder n d)])
|
|
|
|
;;; (if (= q 0)
|
|
|
|
;;; (/ 1.0 (f d n))
|
|
|
|
;;; (if (= r 0)
|
|
|
|
;;; (inexact q)
|
|
|
|
;;; (+ q (f r d)))))))
|
|
|
|
|
|
|
|
(define (ratnum->flonum num)
|
|
|
|
(define (rat n m)
|
|
|
|
(let-values ([(q r) (quotient+remainder n m)])
|
|
|
|
(if (= r 0)
|
|
|
|
(inexact q)
|
|
|
|
(fl+ (inexact q) (fl/ 1.0 (rat m r))))))
|
|
|
|
(define (pos n d)
|
|
|
|
(cond
|
|
|
|
[(> n d) (rat n d)]
|
|
|
|
[(even? n)
|
|
|
|
(* (pos (sra n 1) d) 2.0)]
|
|
|
|
[(even? d)
|
|
|
|
(/ (pos n (sra d 1)) 2.0)]
|
|
|
|
[else
|
|
|
|
(/ (rat d n))]))
|
|
|
|
(let ([n ($ratnum-n num)] [d ($ratnum-d num)])
|
|
|
|
(if (> n 0)
|
|
|
|
(pos n d)
|
2008-03-01 21:54:27 -05:00
|
|
|
(- (pos (- n) d)))))
|
2008-01-06 02:27:23 -05:00
|
|
|
|
2008-05-19 00:41:53 -04:00
|
|
|
(define (err who x)
|
|
|
|
(die who (if (number? x) "invalid argument" "not a number") x))
|
2007-06-15 01:53:34 -04:00
|
|
|
|
2008-05-25 13:37:41 -04:00
|
|
|
|
2006-11-23 19:48:14 -05:00
|
|
|
(define binary+
|
|
|
|
(lambda (x y)
|
|
|
|
(cond
|
2007-01-21 20:36:22 -05:00
|
|
|
[(fixnum? x)
|
2006-11-23 19:48:14 -05:00
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_fxfxplus" x y)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_fxbnplus" x y)]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? y)
|
2007-06-18 07:29:39 -04:00
|
|
|
($fl+ ($fixnum->flonum x) y)]
|
2007-05-21 19:35:16 -04:00
|
|
|
[(ratnum? y)
|
|
|
|
($make-ratnum
|
|
|
|
(+ (* x ($ratnum-d y)) ($ratnum-n y))
|
|
|
|
($ratnum-d y))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[(compnum? y)
|
|
|
|
($make-compnum
|
|
|
|
(binary+ x ($compnum-real y))
|
|
|
|
($compnum-imag y))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary+ x ($cflonum-real y))
|
|
|
|
($cflonum-imag y))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '+ y)])]
|
2006-11-23 19:48:14 -05:00
|
|
|
[(bignum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_fxbnplus" y x)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_bnbnplus" x y)]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? y)
|
|
|
|
($fl+ (bignum->flonum x) y)]
|
2007-05-21 19:35:16 -04:00
|
|
|
[(ratnum? y)
|
|
|
|
($make-ratnum
|
|
|
|
(+ (* x ($ratnum-d y)) ($ratnum-n y))
|
|
|
|
($ratnum-d y))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[(compnum? y)
|
|
|
|
($make-compnum
|
|
|
|
(binary+ x ($compnum-real y))
|
|
|
|
($compnum-imag y))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary+ x ($cflonum-real y))
|
|
|
|
($cflonum-imag y))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '+ y)])]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
2007-06-18 07:29:39 -04:00
|
|
|
($fl+ x ($fixnum->flonum y))]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(bignum? y)
|
|
|
|
($fl+ x (bignum->flonum y))]
|
|
|
|
[(flonum? y)
|
|
|
|
($fl+ x y)]
|
2007-05-21 19:35:16 -04:00
|
|
|
[(ratnum? y)
|
|
|
|
($fl+ x (ratnum->flonum y))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
($fl+ x ($cflonum-real y))
|
|
|
|
($cflonum-imag y))]
|
|
|
|
[(compnum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary+ x ($compnum-real y))
|
|
|
|
(inexact ($compnum-imag y)))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '+ y)])]
|
2007-05-21 19:35:16 -04:00
|
|
|
[(ratnum? x)
|
|
|
|
(cond
|
|
|
|
[(or (fixnum? y) (bignum? y))
|
|
|
|
($make-ratnum
|
|
|
|
(+ (* y ($ratnum-d x)) ($ratnum-n x))
|
|
|
|
($ratnum-d x))]
|
|
|
|
[(flonum? y)
|
|
|
|
($fl+ y (ratnum->flonum x))]
|
|
|
|
[(ratnum? y)
|
|
|
|
(let ([n0 ($ratnum-n x)] [n1 ($ratnum-n y)]
|
|
|
|
[d0 ($ratnum-d x)] [d1 ($ratnum-d y)])
|
|
|
|
;;; FIXME: inefficient
|
|
|
|
(/ (+ (* n0 d1) (* n1 d0)) (* d0 d1)))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[(compnum? y)
|
|
|
|
($make-compnum
|
|
|
|
(binary+ x ($compnum-real y))
|
|
|
|
($compnum-imag y))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary+ x ($cflonum-real y))
|
|
|
|
($cflonum-imag y))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '+ y)])]
|
|
|
|
[(compnum? x)
|
|
|
|
(cond
|
|
|
|
[(or (fixnum? y) (bignum? y) (ratnum? y))
|
|
|
|
($make-compnum
|
|
|
|
(binary+ ($compnum-real x) y)
|
|
|
|
($compnum-imag x))]
|
|
|
|
[(compnum? y)
|
2008-05-25 13:37:41 -04:00
|
|
|
($make-rectangular
|
2008-05-19 00:41:53 -04:00
|
|
|
(binary+ ($compnum-real x) ($compnum-real y))
|
|
|
|
(binary+ ($compnum-imag x) ($compnum-imag y)))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(flonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary+ y ($compnum-real x))
|
|
|
|
(inexact ($compnum-imag x)))]
|
|
|
|
[(cflonum? y)
|
2008-07-25 20:46:34 -04:00
|
|
|
($make-cflonum
|
2008-05-25 13:37:41 -04:00
|
|
|
(binary+ ($compnum-real x) ($cflonum-real y))
|
|
|
|
(binary+ ($compnum-imag x) ($cflonum-imag y)))]
|
|
|
|
[else (err '+ y)])]
|
|
|
|
[(cflonum? x)
|
|
|
|
(cond
|
|
|
|
[(cflonum? y)
|
2008-07-25 20:46:34 -04:00
|
|
|
($make-cflonum
|
2008-05-25 13:37:41 -04:00
|
|
|
(binary+ ($cflonum-real x) ($cflonum-real y))
|
|
|
|
(binary+ ($cflonum-imag x) ($cflonum-imag y)))]
|
|
|
|
[(flonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
($fl+ ($cflonum-real x) y)
|
|
|
|
($cflonum-imag x))]
|
|
|
|
[(or (fixnum? y) (bignum? y) (ratnum? y))
|
|
|
|
($make-compnum
|
|
|
|
(binary+ ($compnum-real x) y)
|
|
|
|
($compnum-imag x))]
|
|
|
|
[(compnum? y)
|
2008-07-25 20:46:34 -04:00
|
|
|
($make-cflonum
|
2008-05-25 13:37:41 -04:00
|
|
|
(binary+ ($cflonum-real x) ($compnum-real y))
|
|
|
|
(binary+ ($cflonum-imag x) ($compnum-imag y)))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '+ y)])]
|
|
|
|
[else (err '+ x)])))
|
2006-11-23 19:48:14 -05:00
|
|
|
|
2007-11-08 19:18:37 -05:00
|
|
|
(define binary-bitwise-and
|
2006-11-23 19:48:14 -05:00
|
|
|
(lambda (x y)
|
|
|
|
(cond
|
2007-01-13 00:42:37 -05:00
|
|
|
[(fixnum? x)
|
2006-11-23 19:48:14 -05:00
|
|
|
(cond
|
2007-05-01 00:04:53 -04:00
|
|
|
[(fixnum? y) ($fxlogand x y)]
|
2006-11-23 19:48:14 -05:00
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_fxbnlogand" x y)]
|
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'bitwise-and "not an exact integer" y)])]
|
2006-11-23 19:48:14 -05:00
|
|
|
[(bignum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_fxbnlogand" y x)]
|
2007-09-12 19:08:45 -04:00
|
|
|
[(bignum? y)
|
2006-11-23 19:48:14 -05:00
|
|
|
(foreign-call "ikrt_bnbnlogand" x y)]
|
2007-09-12 19:08:45 -04:00
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'bitwise-and "not an exact integer" y)])]
|
|
|
|
[else (die 'bitwise-and "not an exact integer" x)])))
|
2006-11-23 19:48:14 -05:00
|
|
|
|
2008-05-18 05:27:55 -04:00
|
|
|
(define binary-bitwise-ior
|
|
|
|
(lambda (x y)
|
|
|
|
(cond
|
|
|
|
[(fixnum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y) ($fxlogor x y)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_fxbnlogor" x y)]
|
|
|
|
[else
|
|
|
|
(die 'bitwise-ior "not an exact integer" y)])]
|
|
|
|
[(bignum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_fxbnlogor" y x)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_bnbnlogor" x y)]
|
|
|
|
[else
|
|
|
|
(die 'bitwise-ior "not an exact integer" y)])]
|
|
|
|
[else (die 'bitwise-ior "not an exact integer" x)])))
|
|
|
|
|
|
|
|
|
|
|
|
(define binary-bitwise-xor
|
|
|
|
(lambda (x y)
|
2008-05-18 06:21:05 -04:00
|
|
|
(define (fxbn x y)
|
|
|
|
(let ([y0 (bitwise-and y (greatest-fixnum))]
|
|
|
|
[y1 (bitwise-arithmetic-shift-right y (- (fixnum-width) 1))])
|
|
|
|
(bitwise-ior
|
|
|
|
($fxlogand ($fxlogxor x y0) (greatest-fixnum))
|
|
|
|
(bitwise-arithmetic-shift-left
|
|
|
|
(bitwise-arithmetic-shift-right
|
|
|
|
(if ($fx>= x 0) y (bitwise-not y))
|
|
|
|
(- (fixnum-width) 1))
|
|
|
|
(- (fixnum-width) 1)))))
|
|
|
|
(define (bnbn x y)
|
|
|
|
(let ([x0 (bitwise-and x (greatest-fixnum))]
|
|
|
|
[x1 (bitwise-arithmetic-shift-right x (- (fixnum-width) 1))]
|
|
|
|
[y0 (bitwise-and y (greatest-fixnum))]
|
|
|
|
[y1 (bitwise-arithmetic-shift-right y (- (fixnum-width) 1))])
|
|
|
|
(bitwise-ior
|
|
|
|
($fxlogand ($fxlogxor x0 y0) (greatest-fixnum))
|
|
|
|
(bitwise-arithmetic-shift-left
|
|
|
|
(binary-bitwise-xor x1 y1)
|
|
|
|
(- (fixnum-width) 1)))))
|
2008-05-18 05:27:55 -04:00
|
|
|
(cond
|
|
|
|
[(fixnum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y) ($fxlogxor x y)]
|
2008-05-18 06:21:05 -04:00
|
|
|
[(bignum? y) (fxbn x y)]
|
2008-05-18 05:27:55 -04:00
|
|
|
[else
|
|
|
|
(die 'bitwise-xor "not an exact integer" y)])]
|
|
|
|
[(bignum? x)
|
|
|
|
(cond
|
2008-05-18 06:21:05 -04:00
|
|
|
[(fixnum? y) (fxbn y x)]
|
|
|
|
[(bignum? y) (bnbn x y)]
|
2008-05-18 05:27:55 -04:00
|
|
|
[else
|
|
|
|
(die 'bitwise-xor "not an exact integer" y)])]
|
|
|
|
[else (die 'bitwise-xor "not an exact integer" x)])))
|
|
|
|
|
2006-11-23 19:48:14 -05:00
|
|
|
|
|
|
|
(define binary-
|
|
|
|
(lambda (x y)
|
|
|
|
(cond
|
|
|
|
[(fixnum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_fxfxminus" x y)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_fxbnminus" x y)]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? y)
|
2007-06-14 13:11:58 -04:00
|
|
|
(if ($fx= x 0)
|
2007-06-17 10:20:19 -04:00
|
|
|
($fl* y -1.0)
|
2007-06-18 07:29:39 -04:00
|
|
|
($fl- ($fixnum->flonum x) y))]
|
2007-06-11 19:49:27 -04:00
|
|
|
[(ratnum? y)
|
|
|
|
(let ([n ($ratnum-n y)] [d ($ratnum-d y)])
|
|
|
|
(binary/ (binary- (binary* d x) n) d))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[(compnum? y)
|
|
|
|
($make-compnum
|
|
|
|
(binary- x ($compnum-real y))
|
|
|
|
(binary- 0 ($compnum-imag y)))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary- x ($cflonum-real y))
|
|
|
|
($fl- 0.0 ($cflonum-imag y)))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '- y)])]
|
2006-11-23 19:48:14 -05:00
|
|
|
[(bignum? x)
|
|
|
|
(cond
|
|
|
|
[(fixnum? y)
|
|
|
|
(foreign-call "ikrt_bnfxminus" x y)]
|
|
|
|
[(bignum? y)
|
|
|
|
(foreign-call "ikrt_bnbnminus" x y)]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? y)
|
|
|
|
($fl- (bignum->flonum x) y)]
|
2007-06-11 19:49:27 -04:00
|
|
|
[(ratnum? y)
|
|
|
|
(let ([n ($ratnum-n y)] [d ($ratnum-d y)])
|
|
|
|
(binary/ (binary- (binary* d x) n) d))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[(compnum? y)
|
|
|
|
($make-compnum
|
|
|
|
(binary- x ($compnum-real y))
|
|
|
|
(binary- 0 ($compnum-imag y)))]
|
2008-05-25 13:37:41 -04:00
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
(binary- x ($cflonum-real y))
|
|
|
|
($fl- 0.0 ($cflonum-imag y)))]
|
2008-05-19 00:41:53 -04:00
|
|
|
[else (err '- y)])]
|
2007-01-20 19:26:17 -05:00
|
|
|
[(flonum? x)
|
|
|
|
(cond
|
2008-05-25 13:37:41 -04:00
|
|
|
[(flonum? y)
|
|
|
|
($fl- x y)]
|
|
|
|
[(cflonum? y)
|
|
|
|
($make-cflonum
|
|
|
|
($fl- x ($cflonum-real y))
|
|