Example #1
0
        private static Expression BigIntConstant(BigInt value)
        {
            int ival;

            if (value.AsInt32(out ival))
            {
                return(Expression.Call(
                           new Func <int, BigInt>(CompilerHelpers.CreateBigInt).GetMethodInfo(),
                           Constant(ival)
                           ));
            }

            long lval;

            if (value.AsInt64(out lval))
            {
                return(Expression.Call(
                           new Func <long, BigInt>(CompilerHelpers.CreateBigInt).GetMethodInfo(),
                           Constant(lval)
                           ));
            }

            return(Expression.Call(
                       new Func <bool, byte[], BigInt>(CompilerHelpers.CreateBigInt).GetMethodInfo(),
                       Constant(value.Sign < 0),
                       CreateArray <byte>(value.Abs().ToByteArray())
                       ));
        }
Example #2
0
        public static BigInt Random(this Random generator, BigInt limit)
        {
            ContractUtils.Requires(limit.Sign > 0, "limit");
            ContractUtils.RequiresNotNull(generator, "generator");

            BigInt res = BigInt.Zero;

            while (true)
            {
                // if we've run out of significant digits, we can return the total
                if (limit == BigInt.Zero)
                {
                    return(res);
                }

                // if we're small enough to fit in an int, do so
                int iLimit;
                if (limit.AsInt32(out iLimit))
                {
                    return(res + generator.Next(iLimit));
                }

                // get the 3 or 4 uppermost bytes that fit into an int
                int    hiData;
                byte[] data  = limit.ToByteArray();
                int    index = data.Length;
                while (data[--index] == 0)
                {
                    ;
                }
                if (data[index] < 0x80)
                {
                    hiData        = data[index] << 24;
                    data[index--] = (byte)0;
                }
                else
                {
                    hiData = 0;
                }
                hiData       |= data[index] << 16;
                data[index--] = (byte)0;
                hiData       |= data[index] << 8;
                data[index--] = (byte)0;
                hiData       |= data[index];
                data[index--] = (byte)0;

                // get a uniform random number for the uppermost portion of the bigint
                byte[] randomData = new byte[index + 2];
                generator.NextBytes(randomData);
                randomData[index + 1] = (byte)0;
                res += new BigInt(randomData);
                res += (BigInt)generator.Next(hiData) << ((index + 1) * 8);

                // sum it with a uniform random number for the remainder of the bigint
                limit = new BigInt(data);
            }
        }
Example #3
0
        public static BigInt Random(this Random generator, BigInt limit) {
            ContractUtils.Requires(limit.Sign > 0, "limit");
            ContractUtils.RequiresNotNull(generator, "generator");

            BigInt res = BigInt.Zero;

            while (true) {
                // if we've run out of significant digits, we can return the total
                if (limit == BigInt.Zero) {
                    return res;
                }

                // if we're small enough to fit in an int, do so
                int iLimit;
                if (limit.AsInt32(out iLimit)) {
                    return res + generator.Next(iLimit);
                }

                // get the 3 or 4 uppermost bytes that fit into an int
                int hiData;
                byte[] data = limit.ToByteArray();
                int index = data.Length;
                while (data[--index] == 0) ;
                if (data[index] < 0x80) {
                    hiData = data[index] << 24;
                    data[index--] = (byte)0;
                } else {
                    hiData = 0;
                }
                hiData |= data[index] << 16;
                data[index--] = (byte)0;
                hiData |= data[index] << 8;
                data[index--] = (byte)0;
                hiData |= data[index];
                data[index--] = (byte)0;

                // get a uniform random number for the uppermost portion of the bigint
                byte[] randomData = new byte[index + 2];
                generator.NextBytes(randomData);
                randomData[index + 1] = (byte)0;
                res += new BigInt(randomData);
                res += (BigInt)generator.Next(hiData) << ((index + 1) * 8);

                // sum it with a uniform random number for the remainder of the bigint
                limit = new BigInt(data);
            }
        }