| Bill Allombert on Tue, 21 Sep 2004 14:29:24 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: [GMP kernel] using mpn_sqrtrem for sqrtr |
On Mon, Sep 20, 2004 at 10:52:02PM +0200, Bill Allombert wrote:
> Hello PARI-dev,
>
> Here a patch that implement sqrtr using the GMP function
> mpn_sqrtrem() (when the GMP kernel is used).
Here a patch for the native kernel that implement the same
algorithm as sqrtr_with_gmp (in the function sqrtr_without_gmp)
With that patch sqrtr_with_gmp and sqrtr_without_gmp should
produce the exact same result.
The problem is that sqrtr_without_gmp is 2.5 times slower than
sqrtr_abs(), which probably means that isqrti is 2.5 times
slower than sqrtr_abs() with the native kernel, which is a bug.
Cheers,
Bill.
Index: src/kernel/none/mp.c
===================================================================
RCS file: /home/cvs/pari/src/kernel/none/mp.c,v
retrieving revision 1.138
diff -u -r1.138 mp.c
--- src/kernel/none/mp.c 14 Sep 2004 20:41:22 -0000 1.138
+++ src/kernel/none/mp.c 21 Sep 2004 10:42:37 -0000
@@ -1505,6 +1505,28 @@
/* Return trunc(sqrt(a))). a must be an non-negative integer*/
GEN isqrti(GEN a) {return racine_r(a,lgefint(a));}
+
+GEN sqrtr_without_gmp(GEN a)
+{
+ GEN res, b, c;
+ long pr=lg(a)-2;
+ long e=expo(a),er=e>>1;
+ int i;
+ if (!signe(a)) return realzero_bit(er);
+ res = cgetr(2 + pr);
+ b = new_chunk(pr + 2);
+ for (i=0; i<pr+2; i++) b[i]=0;
+ c = ishiftr_spec(a,pr+2,(e&1)?0:-1);
+ setsigne(c,1);
+ c = racine_r(c,(pr<<1)+4);
+ i=pr+2;
+ if (c[i]<0)
+ while( !++c[--i]);
+ for(i=2;i<pr+2;i++) res[i]=c[i];
+ res[1] = evalsigne(1) | evalexpo(er);
+ avma=(pari_sp)res;
+ return res;
+}
/* Normalize a non-negative integer. */
GEN