Hmm...

I guess a part of my problem was figuring out how this was correct for
very small values. The condition where it's executed is
(pn<=nn&&qn<=nn)

Here, nn means that the term exceeds roughly 308 digits, and qn
represents the denominator.

And... testing shows that this actually doesn't work for very small values.

   A=: (?10x^350) % ?10x^50
   B=: (?10x^50) % ?10x^350
   0.0+A,B
2.72349e299 0
   (0.0+(B*10x^50))%10^50
1.97574e_300

So.. I only need to focus on this for its significance when A is very large.

Anyways, your perspective helped. A lot.

Thanks,

-- 
Raul

On Thu, Oct 13, 2022 at 2:42 PM Henry Rich <henryhr...@gmail.com> wrote:
>
> The code you post divides (n*1e20)/d and treats the low 5 digits of result
> as a fractional part. It multiplies the fraction by 1e20 and then divides
> that by 1e20, rounding. (It may use fewer digits in some cases.). The
> rounded result is transferred to the quotient.
>
> I don't see that this is guaranteed to be correct for big values.  If you
> need to round the quotient, why don't you add half the denominator to the
> numerator before using the gmp function?  You might need to multiply both
> parts by 2 first.
>
> Henry Rich
>
> On Thu, Oct 13, 2022, 10:49 AM Raul Miller <rauldmil...@gmail.com> wrote:
>
> > https://github.com/jsoftware/jsource/blob/master/jsrc/k.c#L306
> >
> > I've been spinning my wheels on this, in the context of
> >
> > https://github.com/jsoftware/jsource/blob/master/test/gxco.ijs#L92
> >
> > In other words, where X p is the numerator of a rational and I pn is
> > the number of "big digits" in p and X q is the denominator of a
> > rational and I qn is the number of "big digits" in q, and p and q are
> > near the limits of values which can represented as IEEE 754 floating
> > points (type D),
> >
> >    k=5+qn;
> >    if(!(c=xdiv(take(sc(-(k+pn)),p),q,XMFLR)))R 0;
> >    cn=AN(c); m=MIN(cn,5); r=cn-(m+k); v=AV(c)+cn-m;
> >    n=0.0; f=1.0; DO(m, n+=f*v[i]; f*=xb;);
> >    d=1.0; DQ(ABS(r), d*=xb;);
> >    x[i]=0>r?n/d:n*d;
> >
> > somehow is more stable than any rewrite than I can come up with. (I
> > keep getting off-by-one least significant bit errors in my rewrites).
> >
> > I think that part of this is that I do not adequately understand what
> > xdiv(take(sc(-(k+pn)),p),q,XMFLR) accomplishes.
> >
> > Part of this, of course, is that I'm trying to come up with something
> > which works where xb is something other than 1e4 (which would be very
> > slow, for me).
> >
> > Anyway... here's an example of a J model of a bad rewrite:
> >
> > base=: x:1e4
> > base=: 2^64x
> > basedigits=: >.10^.base
> >
> > X2D2=: {{
> >  if. 0=y do. 0.0
> >  else.
> >   yn=. >.base^.y
> >   yl=. 0.0+(yn#base)#:|y
> >   ys=. *y
> >   ys*base#.yl
> >  end.
> > }}
> >
> > R2Db=: {{
> >   y=. y%+./y assert. (,2) -: $y
> >   'N D'=. y
> >    'en ed'=. (>.base^.|y)-<.308%basedigits
> >    e=. 0
> >    if. 0<en do. N=. N <.@% base^en [ e=. en end.
> >    if. 0<ed do. D=. D <.@% base^ed [ e=. e-ed end.
> >    (N %&X2D2 D)*<.base^e
> > }}
> >
> > R2D=: R2Db"1
> >
> > f1=: 4 : 0
> >  p=: (_1^x ?@$ 2) * x ?@$ y
> >  q=: 2+($p) ?@$ 20
> >  e=: (_1^($p) ?@$ 2),.q^x:<.350*q^.10
> >  e=: e % +./"1|e
> >  d=: p - R2D p (({.@]+*&{:),.{:@])"0 1  e
> >  assert. 0 = d
> >  1
> > )
> >
> > 1000 f1"0 ] 10^2 3
> >
> > This seems like it should be simple, but I've been staring at it too
> > long and am not seeing the forest because of all the trees...
> >
> > If anyone has insight on this one, I'd love to hear it.
> >
> > Thanks,
> >
> > --
> > Raul
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
> >
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to