Ruud H.G. van Tol on Sun, 15 Dec 2024 13:15:47 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: digits of a float |
On 2024-12-15 12:31, Bill Allombert wrote:
On Sat, Dec 14, 2024 at 12:07:29PM +0100, Ruud H.G. van Tol wrote:How to properly isolate a digit of a float? Example: ? my(n=19437); localprec(n+2); Pi *10^(n-1) \1 %10 %4 = 7 ? my(n=19437); localprec(n+3); Pi *10^(n-1) \1 %10 %5 = 6 That type of code depends on the number of 9-digits in the decimal expansion of the value. See also https://oeis.org/A000796, which uses localprec(n*6\5+29). What clean ways are there?This is difficult. One need to round toward 0 instead of rounding to nearest as usual. In this instance the number end by 574699992... which is (correctly) rounded to nearest by PARI to 5747..... I wrote this, which increase the accuracy until there is no more ambiguity. { my(n=19437,z); for(m=n+1,oo, localprec(m+1); z = round(Pi *10^m)/10^m; if(abs(z-Pi)>10^-(m+1),break)); z*10^(n-1)\1%10 } but this need to be checked more carefully
Yes, I have used something similar. Also for non-Pi-cases. Bigger steps are feasible:? my(r=List(), p=0); for(i=1, 10, localprec(p+1); listput(~r, p=precision(.))); Vec(r)
% [19, 38, 57, 77, 96, 115, 134, 154, 173, 192]Specifically for Pi, I noticed that 4*atan(1) has a higher precision than default:
? localprec(1); [ precision(.), precision(Pi), precision(4*atan(1)) ] % [19, 19, 38]The "precision" mentioned in the printf-docs is yet another type of precision: ? localprec(1); my(v=1-10^-40); strprintf("%s | %s | %.*f", precision(.), 1.-v, 28, v*1.)
% "19 | 0.E-18 | 0.9999999999999999999731564544" -- Ruud