Bill Allombert on Mon, 22 Jan 2024 13:22:46 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: log_int_rat


On Mon, Jan 22, 2024 at 11:56:29AM +0100, Ruud H.G. van Tol wrote:
> 
> On 2024-01-22 11:25, Ruud H.G. van Tol wrote:
> > [...]
> > On the non-discrete code branch:
> > 
> >   a(n) = localbitprec(logint(n+2,2)); 1 + n + floor(n*log(2)/log(3/2));
> > 
> > with test:
> > 
> >   {default(parisizemax,2^30); my(v=alist(2^20)); for(n=1,#v,
> > (v[n]!=a(n-1)) && print(n);break);}
> > 
> > I received this report:
> > 
> > > that code wrong result a(83690) = 226760 (in a 32-bit pari)
> > > with no hint that it didn't know right from wrong.
> > 
> > 
> > ? my(v=alist(83700)); v[83691]
> > cpu time = 485 ms, real time = 490 ms.
> > % 226759
> 
> My current guess is that it needs something more like
>   localbitprec(2*n+1); ...

No, the issue run deeper than that.

? 83690*log(2)/log(3/2)
%19 = 143068.9999732032502851373630

To get the correct floor() you need to 'skip' the four 9 digits.

Now consider this other example
? \p200
   realprecision = 202 significant digits (200 digits displayed)
? 282896829528374*log(2)/log(3/2)
%22 = 483615324366282.99999999999999972480016707721405476228331340155888020025561304044368677831069845019580206096595446347432023644929708447688723054552955187462035282662255837003805169825570885964555199

Here you have to skip fifteen 9 digits.
So unless you have a formula for the maximal number of 9 or zeros that can
appear, you cannot get a sufficient precision.

Instead I offer this (written while waiting for the water to boil, so be careful)

safedigits(f)=
{
  my(z=f(),e=exponent(z),k=3,r);
  while(1,
    my(K=10^k,y=round(K*z,&r));
    if (r<0 && (y+1)%K>1, return(y\K));
    k*=2;
    localbitprec(e+4*k);z=f());
}
a(n) = localbitprec(logint(n+2,2)); 1+n+safedigits(()->(n*log(2)/log(3/2)));

Cheers,
Bill