/* Author: Pate Williams (c) 1997 Algorithm 5.3.5 (h(D) Counting Reduced Forms). See "A Course in Computational Algebraic Number Theory" by Henri Cohen page 223. */ #include #include "lip.h" void h(verylong zD, verylong *zh) { verylong zB = 0, za = 0, zb = 0, zc = 0, zq = 0; verylong zr = 0, zs = 0; zone(zh); zintoz(zsmod(zD, 2l), &zb); zcopy(zD, &za); zabs(&za); zsdiv(za, 3l, &zc); zsqrt(zc, &zB, &za); L2: zsq(zb, &za); zsub(za, zD, &zc); zsdiv(zc, 4l, &zq); zcopy(zb, &za); if (zscompare(za, 1l) <= 0) { zone(&za); goto L4; } L3: zmod(zq, za, &zr); if (zscompare(zr, 0l) == 0) { zsq(za, &zc); if (zcompare(za, zb) == 0 || zcompare(zc, zq) == 0 || zscompare(zb, 0l) == 0) { zsadd(*zh, 1l, &zc); zcopy(zc, zh); } else { zsadd(*zh, 2l, &zc); zcopy(zc, zh); } } L4: zsadd(za, 1l, &zc); zcopy(zc, &za); zsq(za, &zc); if (zcompare(zc, zq) <= 0) goto L3; zsadd(zb, 2l, &zc); zcopy(zc, &zb); if (zcompare(zb, zB) <= 0) goto L2; zfree(&zB); zfree(&za); zfree(&zb); zfree(&zc); zfree(&zq); zfree(&zr); zfree(&zs); } int main(void) { verylong zD = 0, za = 0, zh = 0; zintoz(- 79l, &zD); printf(" D h\n"); while (zscompare(zD, 0l) < 0) { h(zD, &zh); printf("%3ld %ld\n", ztoint(zD), ztoint(zh)); zsadd(zD, 1l, &za); zcopy(za, &zD); } zfree(&zD); zfree(&za); zfree(&zh); return 0; }