On 11/29/2012 07:55 AM, Matthew Flatt wrote:
At Thu, 29 Nov 2012 14:44:38 +0000, Greg Graham wrote:
There are a couple of issues here.

First, the inexact number 4.225 is actually slightly smaller than the
exact value 4.225:

[...]

Even if you use the exact number 4.225, though, you get a "2" as the
last digit:

  > (real->decimal-string #e4.225 2)
  "4.22"

That's because rounding in Racket is to "even" --- a different
convention than the one taught to most students, but one that it often
preferred in computing (because it often reduces accumulated error, as I
understand it).

Right. If you want to implement rounding with ties rounded away from zero, you've got to do it yourself. Here's an implementation, which takes an optional `scale' argument:

(define (round/ties-away x [scale 1])
  (cond [(not (= scale 1))  (/ (round/ties-away (* x scale) 1) scale)]
        [(x . < . 0)  (truncate (- x 1/2))]
        [else         (truncate (+ x 1/2))]))

> (real->decimal-string (round/ties-away #e4.225 100) 2)
"4.23"

You'd still need to compute using exact numbers, though, because as Matthew said, 4.225 is a little smaller than #e4.225:

> (real->decimal-string (round/ties-away 4.225 100) 2)
"4.22"

Also, multiplying and dividing inexact numbers by non-powers-of-two introduces a little bit of error, which can make scaling before rounding produce the wrong result. With exact numbers, though, it's, uh, exact.

Neil ⊥

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to