1package provide Gmpz 2.0
2package require Gmp 2.0
3#
4# interface to arbitrary precison integer arithmetic
5#
6namespace eval ::gmp:: {
7    namespace export zadd zsub zmul zdiv zrem zmod zgcd zcmp zand zior zcom zneg zabs zsqrt zcvt
8}
9
10proc ::gmp::zget_str {rad mpz} {
11    if {$rad < 2 || $rad > 36} {
12	error "radix $rad out of bounds, min 2, max 36"
13    }
14    set mpzo [binary format x[expr {[mpz_sizeinbase $mpz $rad]+2}]]
15    mpz_get_str mpzo $rad $mpz
16}
17proc ::gmp::zunary {fn i1} {
18    set mpz1 [binary format x[::ffidl::info sizeof mpz_struct]]
19    set mpz2 [binary format x[::ffidl::info sizeof mpz_struct]]
20    mpz_init_set_str mpz1 $i1 10
21    mpz_init mpz2
22    $fn mpz2 $mpz1
23    set r [zget_str 10 $mpz2]
24    mpz_clear mpz1
25    mpz_clear mpz2
26    set r
27}
28proc ::gmp::zbinary {fn i1 i2} {
29    set mpz1 [binary format x[::ffidl::info sizeof mpz_struct]]
30    set mpz2 [binary format x[::ffidl::info sizeof mpz_struct]]
31    set mpz3 [binary format x[::ffidl::info sizeof mpz_struct]]
32    mpz_init_set_str mpz1 $i1 10
33    mpz_init_set_str mpz2 $i2 10
34    mpz_init mpz3
35    $fn mpz3 $mpz1 $mpz2
36    set r [zget_str 10 $mpz3]
37    mpz_clear mpz1
38    mpz_clear mpz2
39    mpz_clear mpz3
40    set r
41}
42proc ::gmp::zbinaryi {fn i1 i2} {
43    set mpz1 [binary format x[::ffidl::info sizeof mpz_struct]]
44    set mpz2 [binary format x[::ffidl::info sizeof mpz_struct]]
45    mpz_init_set_str mpz1 $i1 10
46    mpz_init_set_str mpz2 $i2 10
47    set r [$fn $mpz1 $mpz2]
48    mpz_clear mpz1
49    mpz_clear mpz2
50    set r
51}
52proc ::gmp::zadd {i1 i2} { zbinary mpz_add $i1 $i2 }
53proc ::gmp::zsub {i1 i2} { zbinary mpz_sub $i1 $i2 }
54proc ::gmp::zmul {i1 i2} { zbinary mpz_mul $i1 $i2 }
55proc ::gmp::zdiv {i1 i2} { zbinary mpz_tdiv_q $i1 $i2 }
56proc ::gmp::zrem {i1 i2} { zbinary mpz_tdiv_r $i1 $i2 }
57proc ::gmp::zmod {i1 i2} { zbinary mpz_mod $i1 $i2 }
58proc ::gmp::zgcd {i1 i2} { zbinary mpz_gcd $i1 $i2 }
59proc ::gmp::zcmp {i1 i2} { zbinaryi mpz_cmp $i1 $i2 }
60proc ::gmp::zand {i1 i2} { zbinary mpz_and $i1 $i2 }
61proc ::gmp::zior {i1 i2} { zbinary mpz_ior $i1 $i2 }
62proc ::gmp::zcom {i1} { zunary mpz_com $i1 }
63proc ::gmp::zneg {i1} { zunary mpz_neg $i1 }
64proc ::gmp::zabs {i1} { zunary mpz_abs $i1 }
65proc ::gmp::zsqrt {i1} { zunary mpz_sqrt $i1 }
66proc ::gmp::zcvt {i1 rad1 rad2} {
67    set mpz1 [binary format x[::ffidl::info sizeof mpz_struct]]
68    mpz_init_set_str mpz1 $i1 $rad1
69    set r [zget_str $rad2 $mpz1]
70    mpz_clear mpz1
71    set r
72}
73