gcl-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]