[racket] Decimal rounding problem
This is because numbers in [4.0,8.0) have one fewer bit with which to
represent the fractional part than numbers in [2.0,4.0). That bit is
needed to represent the larger integer part.
Alternatively, you can understand it in terms of how many flonums there
are between each integer. That number decreases as the numbers get
farther from zero:
> (require unstable/flonum) ; (require math/flonum) on the nightlies
> (flonums-between 2.0 3.0)
2251799813685248
> (flonums-between 4.0 5.0)
1125899906842624
It gets really sparse, eventually:
> (flonums-between (expt 2.0 52.0) (+ (expt 2.0 52.0) 1.0))
1
Neil ⊥
On 11/29/2012 08:48 AM, Robby Findler wrote:
> But why does 3.225 round differently than 4.225?
>
> I see that this is different:
>
>> (> 3.225 #e3.225)
> #t
>
> but I would have thought that the integer part wouldn't affect
> anything here since floats have those parts separate? I thought?
>
> Robby
>
> On Thu, Nov 29, 2012 at 8:55 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>> At Thu, 29 Nov 2012 14:44:38 +0000, Greg Graham wrote:
>>> I am trying to report GPA calculation results to 2 decimal places, so I thought
>>> real->decimal-string would do the trick. However, the following behavior
>>> surprised me:
>>>
>>>> (real->decimal-string 3.225 2)
>>> "3.23"
>>>> (real->decimal-string 4.225 2)
>>> "4.22"
>>>
>>> I would like the second answer to be "4.23", which is what a student would
>>> expect to see if they did the calculations themselves. The documentation for
>>> real->decimal-string says that it first converts the argument to an exact
>>> number. I suspect the problem has something to do with this:
>>>
>>>> (inexact->exact 4.225)
>>> 4 126663739519795/562949953421312
>>>> (/ 126663739519795.0 562949953421312.0)
>>> 0.22499999999999964
>>>
>>> Is there another rounding function that would just round the floating point
>>> without going through the conversion to exact?
>>
>> There are a couple of issues here.
>>
>> First, the inexact number 4.225 is actually slightly smaller than the
>> exact value 4.225:
>>
>> > (< 4.225 #e4.225)
>> #t
>> > (pretty-print-exact-as-decimal #t)
>> > (inexact->exact 4.225)
>> 4.2249999999999996447286321199499070644378662109375
>>
>> So, that's one reason to argue that "4.22" is the right answer.
>>
>>
>> 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).
>>
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
>