Implement procedures to control flonum rounding mode.
authorChris Hanson <org/chris-hanson/cph>
Mon, 29 Sep 2008 05:41:51 +0000 (05:41 +0000)
committerChris Hanson <org/chris-hanson/cph>
Mon, 29 Sep 2008 05:41:51 +0000 (05:41 +0000)
v7/src/runtime/fixart.scm
v7/src/runtime/runtime.pkg

index 2f3d2848f8ee0af5e94db4e94335eb469a965300..e14b85a11d373b95262c4726f3d45065f18ef120 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Id: fixart.scm,v 1.20 2008/02/14 02:35:02 cph Exp $
+$Id: fixart.scm,v 1.21 2008/09/29 05:41:48 cph Exp $
 
 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
@@ -152,4 +152,57 @@ USA.
 
 (define (->flonum x)
   (guarantee-real x '->FLONUM)
-  (exact->inexact (real-part x)))
\ No newline at end of file
+  (exact->inexact (real-part x)))
+\f
+(define-primitives
+  (float-rounding-modes 0)
+  (get-float-rounding-mode 0)
+  (set-float-rounding-mode 1))
+
+(define float-rounding-mode-names
+  '#(TO-NEAREST TOWARD-ZERO DOWNWARD UPWARD))
+
+(define (flo:rounding-modes)
+  (let ((n (vector-length float-rounding-mode-names))
+       (m (float-rounding-modes)))
+    (let loop ((i 0) (names '()))
+      (if (fix:< i n)
+         (loop (fix:+ i 1)
+               (if (fix:= (fix:and (fix:lsh 1 i) m) 0)
+                   names
+                   (cons (vector-ref float-rounding-mode-names i) names)))
+         names))))
+
+(define (flo:rounding-mode)
+  (let ((m (get-float-rounding-mode)))
+    (if (not (fix:< m (vector-length float-rounding-mode-names)))
+       (error "Unknown float rounding mode:" m))
+    (vector-ref float-rounding-mode-names m)))
+
+(define (flo:set-rounding-mode! mode)
+  (set-float-rounding-mode (%mode-name->number mode 'FLO:SET-ROUNDING-MODE!)))
+
+(define (flo:with-rounding-mode mode thunk)
+  (let ((inside-mode (%mode-name->number mode 'FLO:WITH-ROUNDING-MODE))
+       (outside-mode))
+    (shallow-fluid-bind (lambda ()
+                         (set! outside-mode (get-float-rounding-mode))
+                         (set-float-rounding-mode inside-mode)
+                         (set! inside-mode)
+                         unspecific)
+                       thunk
+                       (lambda ()
+                         (set! inside-mode (get-float-rounding-mode))
+                         (set-float-rounding-mode outside-mode)
+                         (set! outside-mode)
+                         unspecific))))
+
+(define (%mode-name->number mode caller)
+  (guarantee-interned-symbol mode caller)
+  (let ((n (vector-length float-rounding-mode-names)))
+    (let loop ((i 0))
+      (if (not (fix:< i n))
+         (error:bad-range-argument mode caller))
+      (if (eq? mode (vector-ref float-rounding-mode-names i))
+         i
+         (loop (fix:+ i 1))))))
\ No newline at end of file
index 4d9c68d15a17b9f4c31984641bb7f5dd3a3aeb41..c482d5631550022d50f6e9b5f5bfbc08bf2f5e2c 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Id: runtime.pkg,v 14.687 2008/09/24 05:57:00 cph Exp $
+$Id: runtime.pkg,v 14.688 2008/09/29 05:41:51 cph Exp $
 
 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
@@ -239,6 +239,9 @@ USA.
          flo:positive?
          flo:round
          flo:round->exact
+         flo:rounding-mode
+         flo:rounding-modes
+         flo:set-rounding-mode!
          flo:sin
          flo:sqrt
          flo:tan
@@ -248,6 +251,7 @@ USA.
          flo:vector-length
          flo:vector-ref
          flo:vector-set!
+         flo:with-rounding-mode
          flo:zero?
          guarantee-index-fixnum
          guarantee-limited-index-fixnum