[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gcl-devel] [Maxima] Stable Maxima version on Gentoo
From: |
Camm Maguire |
Subject: |
Re: [Gcl-devel] [Maxima] Stable Maxima version on Gentoo |
Date: |
Tue, 15 Jan 2013 16:28:39 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) |
Greetings!
Raymond Toy <address@hidden> writes:
>>>>>> "Camm" == Camm Maguire <address@hidden> writes:
>
> Camm> Greetings!
> Camm> Raymond Toy <address@hidden> writes:
>
> >>>>>>> "Camm" == Camm Maguire <address@hidden> writes:
> >>
> Camm> Greetings!
> Camm> "Stewart W. Wilson" <address@hidden> writes:
> >>
> >> >> The fix does not seem to be exactly trivial. Please see the
> attached
> >> >> paper by Steele and White from 1990.
> >> >>
> >>
> Camm> Thanks so much for this reference!
> >>
> Camm> Unfortunately, using up to forty 32bit words in bignum arithmetic to
> Camm> print out floats looks prohibitively expensive, although the
> algorithm
> Camm> does appear to work nicely, at least when coded in lisp.
> >>
> >> FWIW, cmucl has a lisp implementation of Dybvig's float printer.
> >> Perhaps that will work for you?
> >>
>
> Camm> It might very well. But is there anything objectionable to a loop
> over
> Camm> strtod when printing? Even in corner cases, it appears very fast.
>
> It seems so random. What happens if strtod prints out xxx...99999
> when the "true" answer is xxxy...0000? And the corner cases might not
> be what you think are corner cases. For example, see
> http://trac.common-lisp.net/cmucl/ticket/1.
>
Well, strtod takes a string and gives a double, without malloc it
appears (as makes sense). This would seem to be an unambiguous mapping
with a definitive algorithm, but of course bugs are always possible.
The key loop in the just committed implementation is:
static int
char_inc(char *b,char *p) {
if (b==p) {
if (*p=='-') {
p++;
memmove(p+1,p,strlen(p)+1);
}
*p='1';
} else if (*p=='9') {
*p='0';
char_inc(b,p-1);
} else if (*p=='.')
char_inc(b,p-1);
else (*p)++;
return 1;
}
#define COMP(a_,b_,c_,d_) ((d_) ? strtod((a_),(b_))==(c_) :
strtof((a_),(b_))==(float)(c_))
static int
truncate_double(char *b,double d,int dp) {
char c[FPRC+9],c1[FPRC+9],*p,*pp,*n;
int j,k;
n=b;
k=strlen(n);
strcpy(c1,b);
for (p=c1;*p && *p!='e';p++);
pp=p>c1 && p[-1]!='.' ? p-1 : p;
for (;pp>c1 && pp[-1]=='0';pp--);
strcpy(pp,p);
if (pp!=p && COMP(c1,&pp,d,dp))
k=truncate_double(n=c1,d,dp);
strcpy(c,n);
for (p=c;*p && *p!='e';p++);
if (p[-1]!='.' && char_inc(c,p-1) && COMP(c,&pp,d,dp)) {
j=truncate_double(c,d,dp);
if (j<k) {
k=j;
n=c;
}
}
if (n!=b) strcpy(b,n);
return k;
}
> At least with the lisp code you have a provably correct algorithm
> guaranteed to produce the correct answer. (Barring bugs in
> implementation, of course!)
>
I'd like to look at this as an improvement at some point. But I do
think controlling allocations will be critical, which at least was not
straightforward when I implemented in lisp the algorithm described in
the originally submitted paper.
Take care,
> Ray
>
>
> _______________________________________________
> Gcl-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/gcl-devel
>
>
>
>
--
Camm Maguire address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah