[racket] Decimal rounding problem

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Thu Nov 29 12:17:55 EST 2012

Oh, of course! Thank you!

Robby

On Thu, Nov 29, 2012 at 10:01 AM, Neil Toronto <neil.toronto at gmail.com> wrote:
> 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
>>
>
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users


Posted on the users mailing list.