代码之家  ›  专栏  ›  技术社区  ›  Bill the Lizard

如何在Java中生成随机BigTunGoT值?

  •  58
  • Bill the Lizard  · 技术社区  · 15 年前

    我需要生成0(包含)到n(包含)范围内任意大的随机整数。我最初的想法是打电话 nextDouble 乘以n,但一旦n大于2 五十三 结果将不再是均匀分布的。

    BigInteger 是否有以下构造函数可用:

    public BigInteger(int numBits, Random rnd)
    

    构造一个随机生成的大整数,在0到(2)的范围内均匀分布 数字 -1),包括在内。

    怎样才能得到0-n范围内的随机值,其中n不是2的幂?

    7 回复  |  直到 6 年前
        1
  •  42
  •   Minix Thomas Pornin    6 年前

    BigInteger randomNumber;
    do {
        randomNumber = new BigInteger(upperLimit.bitLength(), randomSource);
    } while (randomNumber.compareTo(upperLimit) >= 0);
    

    int nlen = upperLimit.bitLength();
    BigInteger nm1 = upperLimit.subtract(BigInteger.ONE);
    BigInteger randomNumber, temp;
    do {
        temp = new BigInteger(nlen + 100, randomSource);
        randomNumber = temp.mod(upperLimit);
    } while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);
    // result is in 'randomNumber'
    

    mod() randomSource

        2
  •  17
  •   Bill the Lizard    15 年前

    BigInteger(int numBits, Random rnd)

    public BigInteger nextRandomBigInteger(BigInteger n) {
        Random rand = new Random();
        BigInteger result = new BigInteger(n.bitLength(), rand);
        while( result.compareTo(n) >= 0 ) {
            result = new BigInteger(n.bitLength(), rand);
        }
        return result;
    }
    

        3
  •  13
  •   Jon Skeet    14 年前

    floor(log2 n) + 1

        4
  •  0
  •   Riduidel    15 年前

    public BigDecimal(BigInteger unscaledVal, int scale)

        5
  •  0
  •   Andy Turner    14 年前

    Andy Turner's Generic Source Code Web Page

    /**
     * There are methods to get large random numbers. Indeed, there is a
     * constructor for BigDecimal that allows for this, but only for uniform
     * distributions over a binary power range.
     * @param a_Random
     * @param upperLimit
     * @return a random integer as a BigInteger between 0 and upperLimit
     * inclusive
     */
    public static BigInteger getRandom(
            Generic_Number a_Generic_Number,
            BigInteger upperLimit) {
        // Special cases
        if (upperLimit.compareTo(BigInteger.ZERO) == 0) {
            return BigInteger.ZERO;
        }
        String upperLimit_String = upperLimit.toString();
        int upperLimitStringLength = upperLimit_String.length();
        Random[] random = a_Generic_Number.get_RandomArrayMinLength(
            upperLimitStringLength);
        if (upperLimit.compareTo(BigInteger.ONE) == 0) {
            if (random[0].nextBoolean()) {
                return BigInteger.ONE;
            } else {
                return BigInteger.ZERO;
            }
        }
        int startIndex = 0;
        int endIndex = 1;
        String result_String = "";
        int digit;
        int upperLimitDigit;
        int i;
        // Take care not to assign any digit that will result in a number larger
        // upperLimit
        for (i = 0; i < upperLimitStringLength; i ++){
            upperLimitDigit = new Integer(
                    upperLimit_String.substring(startIndex,endIndex));
            startIndex ++;
            endIndex ++;
            digit = random[i].nextInt(upperLimitDigit + 1);
            if (digit != upperLimitDigit){
                break;
            }
            result_String += digit;
        }
        // Once something smaller than upperLimit guaranteed, assign any digit
        // between zero and nine inclusive
        for (i = i + 1; i < upperLimitStringLength; i ++) {
            digit = random[i].nextInt(10);
            result_String += digit;
        }
        // Tidy values starting with zero(s)
        while (result_String.startsWith("0")) {
            if (result_String.length() > 1) {
                result_String = result_String.substring(1);
            } else {
                break;
            }
        }
        BigInteger result = new BigInteger(result_String);
        return result;
    }
    
        6
  •  0
  •   lpsun    7 年前

    new BigInteger(n.bitLength(), new SecureRandom()).mod(n)
    
        7
  •  -2
  •   phuclv    8 年前

    type BigIntegerRandom() =
        static let internalRandom = new Random()
    
        /// Returns a BigInteger random number of the specified number of bytes.
        static member RandomBigInteger(numBytes:int, rand:Random) =
            let r = if rand=null then internalRandom else rand
            let bytes : byte[] = Array.zeroCreate (numBytes+1)
            r.NextBytes(bytes)
            bytes.[numBytes] <- 0uy
            bigint bytes
    
        /// Returns a BigInteger random number from 0 (inclusive) to max (exclusive).
        static member RandomBigInteger(max:bigint, rand:Random) =
            let rec getNumBytesInRange num bytes = if max < num then bytes else getNumBytesInRange (num * 256I) bytes+1
            let bytesNeeded = getNumBytesInRange 256I 1
            BigIntegerRandom.RandomBigInteger(bytesNeeded, rand) % max
    
        /// Returns a BigInteger random number from min (inclusive) to max (exclusive).
        static member RandomBigInteger(min:bigint, max:bigint, rand:Random) =
            BigIntegerRandom.RandomBigInteger(max - min, rand) + min