Dear Marc or Brad, I'd be curious to know if there is any way to ensure that calculations in Gambit become completely exact?
What I'm looking for is that as flonum operations by nature are inexact (+ 0.1 0.2 would be a good example), would there be a way to use bignum-only operations, or have some kind of configuration that uses fixnum when applicable and otherwise bignum only.
Is there anything like this - I know fixnum and flonum ops can be accessed under fixnum+ etc., but what about the bignums, (bignum+ 99999999999999999999 2)?
Afaik the bignum library is completely exact for + and -, and has a precision of at least 10^-17 for the rest of the operations (* / modulo sqrt expt etc), is this the way?
Kind regards, Mikael
Afficher les réponses par date
On Feb 4, 2012, at 4:45 AM, Mikael wrote:
Dear Marc or Brad, I'd be curious to know if there is any way to ensure that calculations in Gambit become completely exact?
What I'm looking for is that as flonum operations by nature are inexact (+ 0.1 0.2 would be a good example), would there be a way to use bignum-only operations, or have some kind of configuration that uses fixnum when applicable and otherwise bignum only.
Do you mean floating-point numbers with parametrized precision? Or do you mean something like this:
[Bradley-Luciers-MacBook-Pro:~] lucier% gsi Gambit v4.6.3
(+ #e1.2 #e3.77)
497/100
When I wrote my homework-on-the web system, there was code like
(define (exact-string->number s) (string->number (string-append "#e" s)))
to make sure that some of the conversions were exact.
Is there anything like this - I know fixnum and flonum ops can be accessed under fixnum+ etc., but what about the bignums, (bignum+ 99999999999999999999 2)?
Well, simple + will do this, calling ##+ to convert the 2 to a (non-normalized) bignum, and then calling ##bignum.+ on the pair.
Afaik the bignum library is completely exact for + and -, and has a precision of at least 10^-17 for the rest of the operations (* / modulo sqrt expt etc), is this the way?
*, modulo and expt are exact (if the first argument to expt is exact and the second is an integer), there is integer-sqrt, which gives you a square root and a remainder.
/ gives you an exact rational when handed two exact integers.
I'm not quite sure what you're looking for. There are ways to compute with the so-called "constructive reals" or "computable reals" (I have the beginnings of such a package, and several packages using different underlying representations exist for Common Lisp), but is that what you want?
Brad
Hi,
I'm not quite sure what you're looking for.
I was just curious if there's any way to do large numbers of + - operations with the knowingness that they're not information-destructive whatsoever. Possibly * and / too. And I see that's doable - neat!
2012/2/4 Bradley Lucier lucier@math.purdue.edu
On Feb 4, 2012, at 4:45 AM, Mikael wrote:
Dear Marc or Brad, I'd be curious to know if there is any way to ensure
that calculations in Gambit become completely exact?
What I'm looking for is that as flonum operations by nature are inexact
(+ 0.1 0.2 would be a good example), would there be a way to use bignum-only operations, or have some kind of configuration that uses fixnum when applicable and otherwise bignum only.
Do you mean floating-point numbers with parametrized precision? Or do you mean something like this:
[Bradley-Luciers-MacBook-Pro:~] lucier% gsi Gambit v4.6.3
(+ #e1.2 #e3.77)
497/100
When I wrote my homework-on-the web system, there was code like
(define (exact-string->number s) (string->number (string-append "#e" s)))
to make sure that some of the conversions were exact.
Wow that's neat!
(exact->inexact (+ #e0.2 #e0.1)) indeed produces 0.3 . Same with multiplication:
(* 0.2 0.1)
.020000000000000004
(exact->inexact (* #e0.2 #e0.1))
.02
(/ 0.3 0.2)
1.4999999999999998
(exact->inexact (/ #e0.3 #e0.2))
1.5
And it certainly works in a wider scope too. :)
(* 12938209384.11111111111111111111113
984537862.222222222222229999933333330000000011111111119999999999922222222222222224) 1.2738157008016247e19
(* #e12938209384.11111111111111111111113
#e984537862.222222222222229999933333330000000011111111119999999999922222222222222224) 79613481300101548404321616589664132883905299223332442517547118401117606549391743970919425255555546373456790123457/6250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
I suppose to get all/a fixed number of decimals, one needs to make a custom variant of exact->inexact? (I suppose what this one does is to fill up a flonum)
(exact->inexact #)
1.2738157008016247e19
Apparently you must use #e rather than inexact->exact to get exact numbers, the latter does something else
(exact->inexact (+ (inexact->exact 0.1) (inexact->exact 0.2)))
.30000000000000004
Based on inspiration from Gambits sources one could make a (make-number-exact n) routine faster than one defined as (exact-string->number (number->string n)).
I suppose for any number of the form [-]digits dot digits, converting numbers to bignum (as you mention below) and then doing bignum+ on them is faster than the #e route.
Is there anything like this - I know fixnum and flonum ops can be accessed under fixnum+ etc., but what about the bignums, (bignum+ 99999999999999999999 2)?
Well, simple + will do this,
calling ##+ to convert the 2 to a (non-normalized) bignum,
Can you give a code example on this one?
Also a modified string->number should be able to produce bignums straight.
and then calling ##bignum.+ on the pair.
There are ways to compute with the so-called "constructive reals" or
"computable reals" (I have the beginnings of such a package, and several packages using different underlying representations exist for Common Lisp), but is that what you want?
What's this about?
Afaik the bignum library is completely exact for + and -, and has a precision of at least 10^-17 for the rest of the operations (* / modulo sqrt expt etc), is this the way?
*, modulo and expt are exact (if the first argument to expt is exact and the second is an integer), there is integer-sqrt, which gives you a square root and a remainder.
/ gives you an exact rational when handed two exact integers.
Cool!
Is there any way to perform fixed-point arithmetics on selected operations (to 3, 6, 9 etc decimals) (I think you call this floating-point with parameterized precision), maybe using a bignum-truncate-to-decimals?
Brad
Kind regards, Mikael
On Feb 5, 2012, at 7:48 AM, Mikael wrote:
Is there any way to perform fixed-point arithmetics on selected operations (to 3, 6, 9 etc decimals) (I think you call this floating-point with parameterized precision), maybe using a bignum-truncate-to-decimals?
In examples/pi/pi.scm there's a small bit of code to do fixed-point operations with k digits in any base:
(define base^k (expt base k)) (define (fixed.+ x y) (+ x y)) (define (fixed.- x y) (- x y)) (define (fixed.* x y) (quotient (* x y) base^k)) (define (fixed.square x) (fixed.* x x)) (define (fixed./ x y) (quotient (* x base^k) y)) (define (fixed.sqrt x) (integer-sqrt (* x base^k))) (define (number->fixed x) (round (* x base^k))) (define (fixed->number x) (/ x base^k))
These operations truncate, not round, number->fixed assumes that its argument is an exact number, and fixed->number returns an exact number, not a flonum, but it's a start.
Brad