Exemplo n.º 1
0
 public void Set(MyUInt256 value)
 {
     for (int i = 0; i < SizeInLongs; i++)
     {
         this._A[i] = value._A[i];
     }
 }
Exemplo n.º 2
0
        public void ExpMod(ulong exponent, MyUInt256 divisor)
        {
            ulong[] exparray = new ulong[SizeInLongs];
            exparray[0] = exponent;

            ExpModInternal(exparray, divisor._A);
        }
Exemplo n.º 3
0
        private static void SeekStateInternal(ref uint state0, ref uint state1, ulong offset, bool reverse)
        {
            if (offset >= _MaximumPeriod)
            {
                offset %= _MaximumPeriod;
            }

            if (offset == 0)
            {
                return;
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier0Inverse : _Multiplier0);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus));

                state0 = unchecked ((uint)((aexpn.ToUInt64() * state0) % _Modulus));
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier1Inverse : _Multiplier1);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus1));

                state1 = unchecked ((uint)((aexpn.ToUInt64() * state1) % _Modulus1));
            }
        }
Exemplo n.º 4
0
        public static MyUInt256 operator +(MyUInt256 a, MyUInt256 b)
        {
            MyUInt256 sum = new MyUInt256(a);

            sum.Add(b);
            return(sum);
        }
Exemplo n.º 5
0
        public static MyUInt256 operator -(MyUInt256 a, MyUInt256 b)
        {
            MyUInt256 diff = new MyUInt256(a);

            diff.Subtract(b);
            return(diff);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="increment">The linear congruential generator's increment constant,
        /// or its additive inverse modulo <paramref name="divisor"/> multiplied by the multiplicative inverse to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong increment, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)
            // caller can substitute Multiplier**-1 and -Increment * Multiplier**-1 to go backwards

            if (offset == 0)
            {
                return(state);
            }

            if (multiplier == 0)
            {
                return(increment);
            }
            else if (multiplier == 1)
            {
                MyUInt256 product = new MyUInt256(increment);
                product.Multiply(offset);
                if (divisor != 0)
                {
                    product.Modulo(divisor);
                }
                return(product.ToUInt64());
            }

            MyUInt256 compdivisor = new MyUInt256(divisor);

            if (divisor == 0)
            {
                compdivisor.Set(0, 1);
            }
            compdivisor.Multiply(multiplier - 1);

            MyUInt256 aexpn = new MyUInt256(multiplier);

            aexpn.ExpMod(offset, compdivisor);  // = Multiplier**Offset

            MyUInt256 fraction = new MyUInt256(aexpn);

            fraction.Subtract(1);
            fraction.Divide(multiplier - 1); // should always divide evenly; that's why divisor has to include (Multiplier - 1) factor though
            fraction.Multiply(increment);    // = Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            MyUInt256 newstate = new MyUInt256(state);

            newstate.Multiply(aexpn); // = Multiplier**Offset * OldState
            newstate.Add(fraction);   // = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            if (divisor != 0)
            {
                newstate.Modulo(divisor);  // now that we've divided by (Multiplier - 1), we can go back to using 'divisor' instead of 'compdivisor'
            }
            return(newstate.ToUInt64());
        } //PrngLcgBase.SeekState
Exemplo n.º 7
0
        public static bool IsZero(MyUInt256 value)
        {
            for (int i = 0; i < SizeInLongs; i++)
            {
                if (value._A[i] != 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 8
0
        } //ModularMath.MultiplicativeInverse(long,long)

        /// <summary>
        /// Computes the multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>.
        /// </summary>
        /// <param name="a">A non-negative integer less than <paramref name="modulus"/>.</param>
        /// <param name="modulus">A non-negative integer defining the integer ring in which <paramref name="a"/> resides.</param>
        /// <returns>The multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>,
        /// or null if no such multiplicative inverse exists.</returns>
        public static MyUInt256 MultiplicativeInverse(MyUInt256 a, MyUInt256 modulus)
        {
            if (a.IsMsbSet() || a.Compare(modulus) >= 0)
            {
                throw new ArgumentOutOfRangeException("a must be a non-negative integer less than modulus");
            }

            if (a.IsZero())
            {
                return(null);
            }

            MyUInt256 mi;

            ExtendedEuclidean(a, modulus, out mi);

            return(mi);
        } //ModularMath.MultiplicativeInverse(MyUInt256,MyUInt256)
Exemplo n.º 9
0
        public void Modulo(MyUInt256 divisor)
        {
            int i;

            for (i = 0; i < SizeInLongs; i++)
            {
                if (divisor._A[i] != 0)
                {
                    break;
                }
            }

            if (i == SizeInLongs)
            {
                return;
            }

            this.ModuloInternal((ulong[])divisor._A.Clone());
        }
Exemplo n.º 10
0
        } //MyUInt256.Divide(ulong)

        public void Divide(MyUInt256 divisor)
        {
            int i;

            for (i = 0; i < SizeInLongs; i++)
            {
                if (divisor._A[i] != 0)
                {
                    break;
                }
            }

            if (i == SizeInLongs)
            {
                throw new DivideByZeroException("divisor must be non-zero");
            }

            this.DivideInternal((ulong[])divisor._A.Clone());
        }
Exemplo n.º 11
0
        } //ModularMath.ExtendedEuclidean(long,long,out ulong)

        /// <summary>
        /// Computes the greatest common divisor (GCD) of <paramref name="a"/> and <paramref name="b"/>,
        /// as well as the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>.
        /// </summary>
        /// <param name="a">A positive integer less than <paramref name="b"/>.</param>
        /// <param name="b">A positive integer greater than <paramref name="a"/>.</param>
        /// <param name="mulInverse">Receives the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>
        /// if <paramref name="a"/> and <paramref name="b"/> are coprime, or null otherwise.</param>
        /// <returns>The greatest common divisor of <paramref name="a"/> and <paramref name="b"/>.</returns>
        public static MyUInt256 ExtendedEuclidean(MyUInt256 a, MyUInt256 b, out MyUInt256 mulInverse)
        {
            if (a.IsZero() || a.Compare(b) >= 0)
            {
                throw new ArgumentOutOfRangeException("a must be a positive integer less than b");
            }

            MyUInt256 r0 = new MyUInt256(b), r1 = new MyUInt256(a); // ordered this way because b > a
            MyUInt256 q = new MyUInt256(), r = new MyUInt256();
            MyUInt256 x0 = new MyUInt256(0), x1 = new MyUInt256(1); // x is a's coefficient; we don't maintain b's coefficient
            MyUInt256 x   = new MyUInt256(1);                       // return multiplicative inverse of 1 if loop breaks before x is assigned and if GCD (q) is 1
            MyUInt256 tmp = new MyUInt256();

            for (; ;)
            {
                r.Set(r0);  // r = r0 % r1
                r.Modulo(r1);
                if (r.IsZero())
                {
                    break;  // break before overwriting previous value of q
                }
                q.Set(r0);  // q = r0 / r1
                q.Divide(r1);

                x.Set(x0);  // x = x0 - q * x1
                tmp.Set(q);
                tmp.Multiply(x1);
                x.Subtract(tmp);

                r0.Set(r1); r1.Set(r);
                x0.Set(x1); x1.Set(x);
            }

            if (x.IsMsbSet())
            {
                x.Add(b);
            }
            mulInverse = (r1.Compare(1) == 0 ? x : null);

            return(r1);
        } //ModularMath.ExtendedEuclidean(MyUInt256,MyUInt256,out MyUInt256)
Exemplo n.º 12
0
        protected static ulong GetMultiplicativeInverse(ulong multiplier, ulong divisor)
        {
            ulong mi;

            if (multiplier >= divisor && divisor != 0)
            {
                return(0);
            }

            if (unchecked ((long)multiplier) < 0 || unchecked ((long)divisor) <= 0)
            {
                mi = ModularMath.MultiplicativeInverse(unchecked ((long)multiplier), unchecked ((long)divisor));
            }
            else
            {
                MyUInt256 mibig = ModularMath.MultiplicativeInverse(new MyUInt256(multiplier), (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor)));
                mi = (mibig == null ? 0 : mibig.ToUInt64());
            }

            return(mi);
        } //PrngLcgBase.GetMultiplicativeInverse
Exemplo n.º 13
0
        public override void SeekBack(ulong offset)
        {
            if (offset == 0)
            {
                return;
            }

            ulong multiplier = this.Multiplier;
            ulong increment  = this.Increment;
            ulong divisor    = this.Modulus;

            ulong mi = GetMultiplicativeInverse(multiplier, divisor);

            if (mi == 0)
            {
                // guessing that modulus is a multiple of period, in which case seeking ahead (modulus - offset) states will reverse by 'offset' states
                SeekAhead(unchecked (divisor - offset));
                return;
            }

            if (increment >= divisor && divisor != 0)
            {
                increment %= divisor;
            }

            if (increment != 0)
            {
                MyUInt256 incrinverse = new MyUInt256(unchecked (divisor - increment));  // negate increment (modulo divisor) to get additive inverse
                incrinverse.Multiply(mi);

                if (divisor != 0)
                {
                    incrinverse.Modulo(divisor);
                }

                increment = incrinverse.ToUInt64();
            }

            this._LcgState = SeekState(this._LcgState, offset, mi, increment, divisor);
        } //PrngLcgBase.SeekBack
Exemplo n.º 14
0
        public void Add(MyUInt256 value)
        {
            unchecked
            {
                ulong carry = 0;

                for (int i = 0; i < SizeInLongs; i++)
                {
                    ulong oldcarry = carry;
                    carry = 0;

                    if ((this._A[i] += value._A[i]) < value._A[i])
                    {
                        carry++;
                    }
                    if ((this._A[i] += oldcarry) < oldcarry)
                    {
                        carry++;
                    }
                }
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Performs discard, modulus, and/or take-from-top transformations on a raw value to produce output according to the PRNG's parameters.
        /// </summary>
        /// <param name="raw">The raw bits to transform.</param>
        /// <param name="limit">The lowest positive integer greater than the maximum desired value.</param>
        /// <returns>A value suitable for output.</returns>
        protected virtual ulong ValueFromRaw(ulong raw, ulong limit)
        {
            if (this.DiscardDivisor != 0)
            {
                raw /= this.DiscardDivisor;

                if (this.OutputDivisor != 0)
                {
                    raw %= this.OutputDivisor;
                }

                return(raw);
            }
            else
            {
                // TO-DO TODO: should we incorporate OutputDivisor somehow?
                MyUInt256 product = new MyUInt256(raw);
                product.Multiply(limit);
                product.Divide(this.Modulus);

                return(product.ToUInt64());
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState)
            // caller can substitute Multiplier**-1 to go backwards

            if (offset == 0)
            {
                return(state);
            }

            MyUInt256 fullmodulus = (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor));

            MyUInt256 aexpn = new MyUInt256(multiplier);

            aexpn.ExpMod(offset, fullmodulus);
            aexpn.Multiply(state);

            if (divisor != 0)
            {
                aexpn.Modulo(fullmodulus);
            }

            return(aexpn.ToUInt64());
        } //PrngLehmerBase.SeekState
Exemplo n.º 17
0
        public void Add(MyUInt256 value)
        {
            unchecked
            {
                ulong carry = 0;

                for (int i = 0; i < SizeInLongs; i++)
                {
                    ulong oldcarry = carry;
                    carry = 0;

                    if ((this._A[i] += value._A[i]) < value._A[i])
                        carry++;
                    if ((this._A[i] += oldcarry) < oldcarry)
                        carry++;
                }
            }
        }
Exemplo n.º 18
0
 public int Compare(MyUInt256 value)
 {
     return Compare(this, value);
 }
Exemplo n.º 19
0
        private static void SeekStateInternal(ref uint state0, ref uint state1, ulong offset, bool reverse)
        {
            if (offset >= _MaximumPeriod)
                offset %= _MaximumPeriod;

            if (offset == 0)
                return;

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier0Inverse : _Multiplier0);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus));

                state0 = unchecked((uint)((aexpn.ToUInt64() * state0) % _Modulus));
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier1Inverse : _Multiplier1);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus1));

                state1 = unchecked((uint)((aexpn.ToUInt64() * state1) % _Modulus1));
            }
        }
Exemplo n.º 20
0
        public static bool IsZero(MyUInt256 value)
        {
            for (int i = 0; i < SizeInLongs; i++)
            {
                if (value._A[i] != 0)
                    return false;
            }

            return true;
        }
Exemplo n.º 21
0
 public static MyUInt256 operator -(MyUInt256 a, MyUInt256 b)
 {
     MyUInt256 diff = new MyUInt256(a);
     diff.Subtract(b);
     return diff;
 }
Exemplo n.º 22
0
 public void Multiply(MyUInt256 value)
 {
     this.MultiplyInternal(value.GetHalfSizeArray());
 }
Exemplo n.º 23
0
 public void Set(MyUInt256 value)
 {
     for (int i = 0; i < SizeInLongs; i++)
         this._A[i] = value._A[i];
 }
Exemplo n.º 24
0
 public MyUInt256(MyUInt256 value)
 {
     this._A = (ulong[])value._A.Clone();
 }
Exemplo n.º 25
0
        public void Divide(MyUInt256 divisor)
        {
            int i;
            for (i = 0; i < SizeInLongs; i++)
                if (divisor._A[i] != 0) break;

            if (i == SizeInLongs)
                throw new DivideByZeroException("divisor must be non-zero");

            this.DivideInternal((ulong[])divisor._A.Clone());
        }
Exemplo n.º 26
0
        public void Modulo(MyUInt256 divisor)
        {
            int i;
            for (i = 0; i < SizeInLongs; i++)
                if (divisor._A[i] != 0) break;

            if (i == SizeInLongs)
                return;

            this.ModuloInternal((ulong[])divisor._A.Clone());
        }
Exemplo n.º 27
0
        /// <summary>
        /// Computes the multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>.
        /// </summary>
        /// <param name="a">A non-negative integer less than <paramref name="modulus"/>.</param>
        /// <param name="modulus">A non-negative integer defining the integer ring in which <paramref name="a"/> resides.</param>
        /// <returns>The multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>,
        /// or null if no such multiplicative inverse exists.</returns>
        public static MyUInt256 MultiplicativeInverse(MyUInt256 a, MyUInt256 modulus)
        {
            if (a.IsMsbSet() || a.Compare(modulus) >= 0)
                throw new ArgumentOutOfRangeException("a must be a non-negative integer less than modulus");

            if (a.IsZero())
                return null;

            MyUInt256 mi;
            ExtendedEuclidean(a, modulus, out mi);

            return mi;
        }
Exemplo n.º 28
0
 public MyUInt256(MyUInt256 value)
 {
     this._A = (ulong[])value._A.Clone();
 }
Exemplo n.º 29
0
 public static int Compare(MyUInt256 a, MyUInt256 b)
 {
     return(CompareInternal(a._A, b._A));
 }
Exemplo n.º 30
0
        /// <summary>
        /// Computes the greatest common divisor (GCD) of <paramref name="a"/> and <paramref name="b"/>,
        /// as well as the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>.
        /// </summary>
        /// <param name="a">A positive integer less than <paramref name="b"/>.</param>
        /// <param name="b">A positive integer greater than <paramref name="a"/>.</param>
        /// <param name="mulInverse">Receives the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>
        /// if <paramref name="a"/> and <paramref name="b"/> are coprime, or null otherwise.</param>
        /// <returns>The greatest common divisor of <paramref name="a"/> and <paramref name="b"/>.</returns>
        public static MyUInt256 ExtendedEuclidean(MyUInt256 a, MyUInt256 b, out MyUInt256 mulInverse)
        {
            if (a.IsZero() || a.Compare(b) >= 0)
                throw new ArgumentOutOfRangeException("a must be a positive integer less than b");

            MyUInt256 r0 = new MyUInt256(b), r1 = new MyUInt256(a);  // ordered this way because b > a
            MyUInt256 q = new MyUInt256(), r = new MyUInt256();
            MyUInt256 x0 = new MyUInt256(0), x1 = new MyUInt256(1);  // x is a's coefficient; we don't maintain b's coefficient
            MyUInt256 x = new MyUInt256(1);  // return multiplicative inverse of 1 if loop breaks before x is assigned and if GCD (q) is 1
            MyUInt256 tmp = new MyUInt256();

            for (; ; )
            {
                r.Set(r0);  // r = r0 % r1
                r.Modulo(r1);
                if (r.IsZero()) break;  // break before overwriting previous value of q

                q.Set(r0);  // q = r0 / r1
                q.Divide(r1);

                x.Set(x0);  // x = x0 - q * x1
                tmp.Set(q);
                tmp.Multiply(x1);
                x.Subtract(tmp);

                r0.Set(r1); r1.Set(r);
                x0.Set(x1); x1.Set(x);
            }

            if (x.IsMsbSet()) x.Add(b);
            mulInverse = (r1.Compare(1) == 0 ? x : null);

            return r1;
        }
Exemplo n.º 31
0
 public int Compare(MyUInt256 value)
 {
     return(Compare(this, value));
 }
Exemplo n.º 32
0
        public void ExpMod(ulong exponent, MyUInt256 divisor)
        {
            ulong[] exparray = new ulong[SizeInLongs];
            exparray[0] = exponent;

            ExpModInternal(exparray, divisor._A);
        }
Exemplo n.º 33
0
        public override ulong SeekSeedBack(ulong seed, ulong offset)
        {
            if (offset == 0)
                return seed;

            ulong multiplier = this.Multiplier;
            ulong increment = this.Increment;
            ulong divisor = this.Modulus;

            ulong mi = GetMultiplicativeInverse(multiplier, divisor);

            if (mi == 0)
            {
                // guessing that modulus is a multiple of period, in which case seeking ahead (modulus - offset) states will reverse by 'offset' states
                return SeekSeedAhead(seed, unchecked(divisor - offset));
            }

            if (increment >= divisor && divisor != 0)
                increment %= divisor;

            if (increment != 0)
            {
                MyUInt256 incrinverse = new MyUInt256(unchecked(divisor - increment));  // negate increment (modulo divisor) to get additive inverse
                incrinverse.Multiply(mi);

                if (divisor != 0)
                    incrinverse.Modulo(divisor);

                increment = incrinverse.ToUInt64();
            }

            return SeekState(this._LcgState, offset, mi, increment, divisor);
        }
Exemplo n.º 34
0
 public void Multiply(MyUInt256 value)
 {
     this.MultiplyInternal(value.GetHalfSizeArray());
 }
Exemplo n.º 35
0
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="increment">The linear congruential generator's increment constant,
        /// or its additive inverse modulo <paramref name="divisor"/> multiplied by the multiplicative inverse to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong increment, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)
            // caller can substitute Multiplier**-1 and -Increment * Multiplier**-1 to go backwards

            if (offset == 0)
                return state;

            if (multiplier == 0)
            {
                return increment;
            }
            else if (multiplier == 1)
            {
                MyUInt256 product = new MyUInt256(increment);
                product.Multiply(offset);
                if (divisor != 0)
                    product.Modulo(divisor);
                return product.ToUInt64();
            }

            MyUInt256 compdivisor = new MyUInt256(divisor);
            if (divisor == 0)
                compdivisor.Set(0, 1);
            compdivisor.Multiply(multiplier - 1);

            MyUInt256 aexpn = new MyUInt256(multiplier);
            aexpn.ExpMod(offset, compdivisor);  // = Multiplier**Offset

            MyUInt256 fraction = new MyUInt256(aexpn);
            fraction.Subtract(1);
            fraction.Divide(multiplier - 1);  // should always divide evenly; that's why divisor has to include (Multiplier - 1) factor though
            fraction.Multiply(increment);  // = Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            MyUInt256 newstate = new MyUInt256(state);
            newstate.Multiply(aexpn);  // = Multiplier**Offset * OldState
            newstate.Add(fraction);  // = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            if (divisor != 0)
                newstate.Modulo(divisor);  // now that we've divided by (Multiplier - 1), we can go back to using 'divisor' instead of 'compdivisor'

            return newstate.ToUInt64();
        }
Exemplo n.º 36
0
 public void Subtract(MyUInt256 value)
 {
     SubtractInternal(this._A, value._A);
 }
Exemplo n.º 37
0
        /// <summary>
        /// Performs discard, modulus, and/or take-from-top transformations on a raw value to produce output according to the PRNG's parameters.
        /// </summary>
        /// <param name="raw">The raw bits to transform.</param>
        /// <param name="limit">The lowest positive integer greater than the maximum desired value.</param>
        /// <returns>A value suitable for output.</returns>
        protected virtual ulong ValueFromRaw(ulong raw, ulong limit)
        {
            if (this.DiscardDivisor != 0)
            {
                raw /= this.DiscardDivisor;

                if (this.OutputDivisor != 0)
                    raw %= this.OutputDivisor;

                return raw;
            }
            else
            {
                // TO-DO TODO: should we incorporate OutputDivisor somehow?
                MyUInt256 product = new MyUInt256(raw);
                product.Multiply(limit);
                product.Divide(this.Modulus);

                return (product.ToUInt64());
            }
        }
Exemplo n.º 38
0
 public static MyUInt256 operator +(MyUInt256 a, MyUInt256 b)
 {
     MyUInt256 sum = new MyUInt256(a);
     sum.Add(b);
     return sum;
 }
Exemplo n.º 39
0
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState)
            // caller can substitute Multiplier**-1 to go backwards

            if (offset == 0)
                return state;

            MyUInt256 fullmodulus = (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor));

            MyUInt256 aexpn = new MyUInt256(multiplier);
            aexpn.ExpMod(offset, fullmodulus);
            aexpn.Multiply(state);

            if (divisor != 0)
                aexpn.Modulo(fullmodulus);

            return aexpn.ToUInt64();
        }
Exemplo n.º 40
0
 public static int Compare(MyUInt256 a, MyUInt256 b)
 {
     return CompareInternal(a._A, b._A);
 }
Exemplo n.º 41
0
 public void Subtract(MyUInt256 value)
 {
     SubtractInternal(this._A, value._A);
 }