# [plt-scheme] Numerical precision

 From: Richard Cleis (rcleis at mac.com) Date: Wed Mar 11 21:41:21 EDT 2009 Previous message: [plt-scheme] Numerical precision Next message: [plt-scheme] Numerical precision Messages sorted by: [date] [thread] [subject] [author]

```You could consider computing everything with integers that represent
the precision in your sim.  (e.g., \$1.23 would be 123 cents or 1230
mills or whatever.) After a division or multiply, rounding or
truncation can be used to create a new integer with the algorithm that
your sim requires.  Converting between the sim integers and \$nn.nn
needs to occur only when you want to display values or accept input.

rac

On Mar 11, 2009, at 2:23 PM, Jaime Vargas wrote:

>
> On Mar 11, 2009, at 3:29 PM, Joe Marshall wrote:
>
>>> (define numerical-precision (make-parameter 2))
>>
>> This is a little odd.  Do you expect to dynamically change the
>> precision?
>> If not, then you might want to make this a regular define rather than
>> a parameter.  If so, however, you'll have to be very careful when you
>> change the precision.
>
> Not within a given simulation. However, I would like to be able to
> specify the
> precision. A normal define will not allow changes, because it
> becomes immutable
> when imported by other modules. And enclosing all the computation
> within
> a parameterize form makes very obvious the precision being used.
>
>>> (define (N)
>>> (expt 10 (numerical-precision)))
>>
>> This is a procedure that raises 10 to the precision power every time
>> it is called.  If the precision doesn't change, you don't need to
>> do this
>> every time.
>>
>>> (define (1/N)
>>> (/ 1 (N)))
>>
>> Likewise, this computes the reciprocal every time it is called.
>>
>>> (define (round:N x)
>>> (* (1/N) (round (* x (N)))))
>>
>> And here you will notice that when you round, you will raise 10 to
>> the
>> correct power twice and take its reciprocal once.
>
> Agreed. I would like to have this computations to happen only once.
> But
> reactive to changes in the numerical-precision parameter.
>
>>> (define (*:N . nums)
>>> (round:N (apply * nums)))
>>>
>>> (define (/:N . nums)
>>> (round:N (apply / nums)))
>>>
>>> (define (+:N . nums)
>>> (round:N (apply + nums)))
>>>
>>> (define (-:N . nums)
>>> (round:N (apply - nums)))
>>
>> You have defined something weird here.  Your arithmetic is no
>> longer associative where you might expect it to be.
>
>
> How so, I don't see the problem. Again, some naive testing.
>
> #lang scheme
>
> (require "accountants-math.ss")
>
> (equal? (* 1/2 (+ 2/3 1/3))
>         (+ (* 1/2 1/3) (* 1/2 2/3)))
> => #t
>
> (equal? (/ (+ 2/3 1/3) 1/2)
>       (+ (/ 2/3 1/2) (/ 1/3 1/2)))
> => #t
>
> (equal? (* 1/2 (- 2/3 1/3))
>       (- (* 1/2 2/3) (* 1/2 1/3)))
> => #t
>
>
> (equal? (/ (- 2/3 1/3) 1/2)
>       (- (/ 2/3 1/2) (/ 1/3 1/2)))
> => #t
>
> -- Jaime
>
>
> _________________________________________________