[Top][All Lists]

[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)


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=='-') {
  } else if (*p=='9') {
  } else if (*p=='.')
  else (*p)++;

  return 1;


#define COMP(a_,b_,c_,d_) ((d_) ? strtod((a_),(b_))==(c_) : 

static int
truncate_double(char *b,double d,int dp) {

  char c[FPRC+9],c1[FPRC+9],*p,*pp,*n;
  int j,k;


  for (p=c1;*p && *p!='e';p++);
  pp=p>c1 && p[-1]!='.' ? p-1 : p;
  for (;pp>c1 && pp[-1]=='0';pp--);
  if (pp!=p && COMP(c1,&pp,d,dp))

  for (p=c;*p && *p!='e';p++);
  if (p[-1]!='.' && char_inc(c,p-1) && COMP(c,&pp,d,dp)) {
    if (j<k) {

  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]