How can I create a random BigDecimal in Java?

后端 未结 3 547
旧时难觅i
旧时难觅i 2021-01-05 17:19

This question: How to generate a random BigInteger describes a way to achieve the same semantics as Random.nextInt(int n) for BigIntegers.

I would like to do the sam

3条回答
  •  攒了一身酷
    2021-01-05 17:43

    I made a post about generating a random BigInteger Andy Turner's answer about generating a random BigInteger. I don't use this directly for generating a random BigDecimal. Essentially my concern is to use independent instances of Random to generate each digit in a number. One problem I noticed is that with Random there are only so many values of and particular number that you get in a row. Also the generation tries to maintain something of an even distribution of generated values. My solution depends on something storing an array or collection of Random instances and calling these. I think this is a good way of going about it and I am trying to find out, so am interested if anyone has any pointers or criticism of this approach.

    /**
     *
     * @param a_Random
     * @param decimalPlaces
     * @param lowerLimit
     * @param upperLimit
     * @return a pseudo randomly constructed BigDecimal in the range from
     * lowerLimit to upperLimit inclusive and that has up to decimalPlaces
     * number of decimal places
     */
    public static BigDecimal getRandom(
            Generic_Number a_Generic_Number,
            int decimalPlaces,
            BigDecimal lowerLimit,
            BigDecimal upperLimit) {
        BigDecimal result;
        BigDecimal range = upperLimit.subtract(lowerLimit);
        BigDecimal[] rangeDivideAndRemainder =
                range.divideAndRemainder(BigDecimal.ONE);
        BigInteger rangeInt = rangeDivideAndRemainder[0].toBigIntegerExact();
        BigInteger intComponent_BigInteger = Generic_BigInteger.getRandom(
                a_Generic_Number,
                rangeInt);
        BigDecimal intComponent_BigDecimal =
                new BigDecimal(intComponent_BigInteger);
        BigDecimal fractionalComponent;
        if (intComponent_BigInteger.compareTo(rangeInt) == 0) {
            BigInteger rangeRemainder =
                    rangeDivideAndRemainder[1].toBigIntegerExact();
            BigInteger fractionalComponent_BigInteger =
                    Generic_BigInteger.getRandom(a_Generic_Number, rangeRemainder);
            String fractionalComponent_String = "0.";
            fractionalComponent_String += fractionalComponent_BigInteger.toString();
            fractionalComponent = new BigDecimal(fractionalComponent_String);
        } else {
            fractionalComponent = getRandom(
                    a_Generic_Number, decimalPlaces);
        }
        result = intComponent_BigDecimal.add(fractionalComponent);
        result.add(lowerLimit);
        return result;
    }
    
    /**
     * Provided for convenience.
     * @param a_Generic_BigDecimal
     * @param decimalPlaces
     * @return a random BigDecimal between 0 and 1 inclusive which can have up
     * to decimalPlaces number of decimal places
     */
    public static BigDecimal getRandom(
            Generic_Number a_Generic_Number,
            int decimalPlaces) {
        //Generic_BigDecimal a_Generic_BigDecimal = new Generic_BigDecimal();
        Random[] random = a_Generic_Number.get_RandomArrayMinLength(
                decimalPlaces);
        //System.out.println("Got Random[] size " + random.length);
        String value = "0.";
        int digit;
        int ten_int = 10;
        for (int i = 0; i < decimalPlaces; i++) {
            digit = random[i].nextInt(ten_int);
            value += digit;
        }
        int length = value.length();
        // Tidy values ending with zero's
        while (value.endsWith("0")) {
            length--;
            value = value.substring(0, length);
        }
        if (value.endsWith(".")) {
            value = "0";
        }
        BigDecimal result = new BigDecimal(value);
        //result.stripTrailingZeros();
        return result;
    }
    

提交回复
热议问题