All pastes #1592445 Raw Edit

Unnamed

public text v1 · immutable
#1592445 ·published 2009-10-04 13:56 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MPCLI
{
    [CLSCompliant(true)]
    public unsafe sealed class IntX
    {
        [StructLayout(LayoutKind.Sequential)]
        private unsafe struct MPZValue
        {
            public int ChunksAllocated;
            public int ChunkCount;
            public uint* Data;
        }

        private const string MPZ_PATH = "libgmp-3.dll";

        #region Imports

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init(ref MPZValue x);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init2(ref MPZValue x, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init_set(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init_set_si(ref MPZValue rop, int op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init_set_ui(ref MPZValue rop, uint op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_init_set_d(ref MPZValue rop, double op);

        [DllImport(MPZ_PATH, CharSet = CharSet.Ansi)]
        private static extern int __gmpz_init_set_str(ref MPZValue rop, string str, int radix);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_clear(ref MPZValue x);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_import(ref MPZValue rop, uint count, int order, uint size, int endian, uint nails, void* op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void* __gmpz_export(void* rop, uint* countp, int order, uint size, int endian, uint nails, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_neg(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_abs(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_sizeinbase(ref MPZValue op, int radix);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmp(ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmp_si(ref MPZValue op1, int op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmp_ui(ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmp_d(ref MPZValue op1, double op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmpabs(ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmpabs_ui(ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_cmpabs_d(ref MPZValue op1, double op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_powm(ref MPZValue rop, ref MPZValue radix, ref MPZValue exp, ref MPZValue mod);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_powm_ui(ref MPZValue rop, ref MPZValue radix, uint exp, ref MPZValue mod);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_pow_ui(ref MPZValue rop, ref MPZValue radix, uint exp);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_ui_pow_ui(ref MPZValue rop, uint radix, uint exp);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_add(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_add_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_sub(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_ui_sub(ref MPZValue rop, uint op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_sub_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_mul(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_mul_si(ref MPZValue rop, ref MPZValue op1, int op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_mul_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_mul_2exp(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_addmul(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_addmul_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_submul(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_submul_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_tdiv_q(ref MPZValue q, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_tdiv_r(ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_tdiv_qr(ref MPZValue q, ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_tdiv_q_ui(ref MPZValue q, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_tdiv_r_ui(ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_tdiv_qr_ui(ref MPZValue q, ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_tdiv_ui(ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_tdiv_q_2exp(ref MPZValue q, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_tdiv_r_2exp(ref MPZValue r, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_cdiv_q(ref MPZValue q, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_cdiv_r(ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_cdiv_qr(ref MPZValue q, ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_cdiv_q_ui(ref MPZValue q, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_cdiv_r_ui(ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_cdiv_qr_ui(ref MPZValue q, ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_cdiv_ui(ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_cdiv_q_2exp(ref MPZValue q, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_cdiv_r_2exp(ref MPZValue r, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fdiv_q(ref MPZValue q, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fdiv_r(ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fdiv_qr(ref MPZValue q, ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_fdiv_q_ui(ref MPZValue q, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_fdiv_r_ui(ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_fdiv_qr_ui(ref MPZValue q, ref MPZValue r, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_fdiv_ui(ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fdiv_q_2exp(ref MPZValue q, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fdiv_r_2exp(ref MPZValue r, ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_mod(ref MPZValue r, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_divexact(ref MPZValue q, ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_divexact_ui(ref MPZValue q, ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_divisible_p(ref MPZValue n, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_divisible_ui_p(ref MPZValue n, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_divisible_2exp_p(ref MPZValue n, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_congruent_p(ref MPZValue n, ref MPZValue c, ref MPZValue d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_congruent_ui_p(ref MPZValue n, uint c, uint d);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_congruent_2exp_p(ref MPZValue n, ref MPZValue c, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_invert(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_and(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_ior(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_xor(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_com(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_popcount(ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_hamdist(ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_scan0(ref MPZValue op, uint starting_bit);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_scan1(ref MPZValue op, uint starting_bit);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_setbit(ref MPZValue rop, uint bit_index);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_clrbit(ref MPZValue rop, uint bit_index);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_combit(ref MPZValue rop, uint bit_index);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_tstbit(ref MPZValue rop, uint bit_index);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_get_ui(ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_get_si(ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern double __gmpz_get_d(ref MPZValue op);

        [DllImport(MPZ_PATH, CharSet = CharSet.Ansi)]
        private static extern void* __gmpz_get_str(StringBuilder str, int radix, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_root(ref MPZValue rop, ref MPZValue op, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_rootrem(ref MPZValue root, ref MPZValue rem, ref MPZValue u, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_sqrt(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_sqrtrem(ref MPZValue rop1, ref MPZValue rop2, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_perfect_power_p(ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_perfect_square_p(ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_probab_prime_p(ref MPZValue n, int reps);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_nextprime(ref MPZValue rop, ref MPZValue op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_gcd(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_gcd_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_gcdext(ref MPZValue g, ref MPZValue s, ref MPZValue t, ref MPZValue a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_gcdext(ref MPZValue g, ref MPZValue s, MPZValue* t, ref MPZValue a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_lcm(ref MPZValue rop, ref MPZValue op1, ref MPZValue op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_lcm_ui(ref MPZValue rop, ref MPZValue op1, uint op2);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_jacobi(ref MPZValue a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_legendre(ref MPZValue a, ref MPZValue p);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_kronecker(ref MPZValue a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_kronecker_si(ref MPZValue a, int b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_kronecker_ui(ref MPZValue a, uint b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_si_kronecker(int a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern int __gmpz_ui_kronecker(uint a, ref MPZValue b);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern uint __gmpz_remove(ref MPZValue rop, ref MPZValue op, ref MPZValue f);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fac_ui(ref MPZValue rop, uint op);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_bin_ui(ref MPZValue rop, ref MPZValue n, uint k);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_bin_uiui(ref MPZValue rop, uint n, uint k);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fib_ui(ref MPZValue fn, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_fib2_ui(ref MPZValue fn, ref MPZValue fnsub1, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_lucnum_ui(ref MPZValue ln, uint n);

        [DllImport(MPZ_PATH, SetLastError = false)]
        private static extern void __gmpz_lucnum2_ui(ref MPZValue ln, ref MPZValue lnsub1, uint n);

        #endregion

        private const int defaultBase = 10;
        private const int wordLength = 32;

        private MPZValue state;

        #region Constructors

        public IntX()
        {
            __gmpz_init(ref this.state);
        }

        public IntX(IntX value)
        {
            __gmpz_init_set(ref this.state, ref value.state);
        }

        public IntX(int value)
        {
            __gmpz_init_set_si(ref this.state, value);
        }

        [CLSCompliant(false)]
        public IntX(uint value)
        {
            __gmpz_init_set_ui(ref this.state, value);
        }

        [CLSCompliant(false)]
        public IntX(uint value, int sign)
        {
            if (value == 0 && sign != 0)
            {
                throw new ArgumentException("The sign is not valid for the specified value.", "sign");
            }

            if (sign >= 0)
            {
                __gmpz_init_set_ui(ref this.state, value);
            }
            else
            {
                __gmpz_init2(ref this.state, 32);

                this.state.ChunkCount = -1;
                this.state.Data[0] = value;
            }
        }

        [CLSCompliant(false)]
        public IntX(uint[] value)
        {
            uint sign = 1;
            fixed (uint* pValue = value)
            {
                for (uint* pValueCurrent = pValue, pValueEnd = pValue + value.Length; pValueCurrent != pValueEnd; pValueCurrent++)
                {
                    if (*pValueCurrent != 0)
                    {
                        sign = 0;
                        break;
                    }
                }
            }

            __gmpz_init(ref this.state);

            if (sign != 0)
            {
                fixed (uint* pValue = value)
                {
                    __gmpz_import(ref this.state, (uint)value.Length, -1, sizeof(int), 0, 0, pValue);
                }

                if (sign < 0)
                {
                    this.state.ChunkCount = -this.state.ChunkCount;
                }
            }
        }

        [CLSCompliant(false)]
        public IntX(uint[] value, int sign)
        {
            __gmpz_init(ref this.state);

            if (sign != 0)
            {
                fixed (uint* pValue = value)
                {
                    __gmpz_import(ref this.state, (uint)value.Length, -1, sizeof(int), 0, 0, pValue);
                }

                if (sign < 0)
                {
                    this.state.ChunkCount = -this.state.ChunkCount;
                }
            }
        }

        public IntX(long value)
        {
            if (value > 0)
            {
                if (value <= Int32.MaxValue)
                {
                    // init2 state 32
                    // pdata eq state data
                    // pdata 0 eq value
                    // state cct eq 1
                }
                else
                {
                    // init2 state 64
                    // pdata eq state
                    // pdata 0 eq value
                    // pdata 1 eq value rs 32
                    // state cct eq 2
                }
            }
            else if (value == 0)
            {
                // init state
            }
            else
            {
                ulong absolute = (ulong)-value;

                if (absolute <= Int32.MaxValue)
                {
                    // init2 state 32
                    // pdata eq state data
                    // pdata 0 eq absolute
                    // state cct eq -1
                }
                else
                {
                    // init2 state 64
                    // pdata eq state data
                    // pdata 0 eq absolute
                    // pdata 1 eq absolute rs 32
                    // state cct eq -2
                }
            }
        }

        public IntX(ulong value)
        {
            if (value == 0)
            {
                // init state
            }
            else
            {
                if (value <= Int32.MaxValue)
                {
                    // init2 state 32
                    // pdata eq state data
                    // pdata 0 eq value
                    // state cct eq 1
                }
                else
                {
                    // init2 state 64
                    // pdata eq state data
                    // pdata 0 eq value
                    // pdata 1 eq value rs 32
                    // state cct eq 2
                }
            }
        }

        ~IntX()
        {
            __gmpz_clear(ref this.state);
        }

        #endregion
    }
}