1

Метод для вычисления рандомного значения числа.
Если я передаю минимальное и максимальное значение одинаковым, в моем случае это 1.9, то в ответ я всегда получаю 1.8. Подскажите, почему так? И как исправить?

public static String random(String m, String mx, int scale) {
Double min = Double.parseDouble(m);
Double max = Double.parseDouble(mx);
Double res;
String rs = "";

res = new BigDecimal((Math.random() * (max - min)) + min).setScale(scale, RoundingMode.FLOOR).doubleValue();

if(scale == 0) {
    rs = new DecimalFormat("#0").format(res).replace(",", ".");
}
else if(scale == 1) {
    rs = new DecimalFormat("#0.0").format(res).replace(",", ".");
}else if(scale ==2) {
    rs = new DecimalFormat("#0.00").format(res).replace(",", ".");
}

return rs;

}

Nowhere Man
  • 15,995
  • 33
  • 19
  • 29
Drop
  • 321

1 Answers1

2

Всё дело в выбранном режиме округления в методе setScale, см. документацию перечисления RoundingMode

Поскольку выбран режим RoundingMode.FLOOR, будет выполняться округление по направлению к -∞, и для переменной точности, заданной параметром scale, округление будет выполняться для соответствующего разряда.

Если добавить параметр RoundingMode к представленному методу, можно написать небольшой тест:

import java.math.*;
import java.text.*;

public class MyClass {

public static String random(String mn, String mx, int scale, RoundingMode roundMode) {
    Double min = Double.parseDouble(mn);
    Double max = Double.parseDouble(mx);
    Double res = new BigDecimal((Math.random() * (max - min)) + min).setScale(scale, roundMode).doubleValue();

    if (scale == 0) {
        return new DecimalFormat("#0").format(res).replace(",", ".");
    }
    return new DecimalFormat("#0." + "0".repeat(scale)).format(res).replace(",", ".");
}

public static void main(String args[]) {
    System.out.println("| scale | FLOOR | CEILING | HALF_DOWN | HALF_UP | HALF_EVEN |");
    System.out.println("|-------|-------|---------|-----------|---------|-----------|");
    for (int scale = 0; scale < 4; scale++) {
        System.out.printf("|   %d   | %-5s |   %-5s |    %-6s |   %-5s |    %-6s |%n", 
            scale, 
            random("1.9", "1.9", scale, RoundingMode.FLOOR),
            random("1.9", "1.9", scale, RoundingMode.CEILING),
            random("1.9", "1.9", scale, RoundingMode.HALF_DOWN),
            random("1.9", "1.9", scale, RoundingMode.HALF_UP),
            random("1.9", "1.9", scale, RoundingMode.HALF_EVEN)
        );
    }
}

}

Результат:

| scale | FLOOR | CEILING | HALF_DOWN | HALF_UP | HALF_EVEN |
|-------|-------|---------|-----------|---------|-----------|
|   0   | 1     |   2     |    2      |   2     |    2      |
|   1   | 1.8   |   1.9   |    1.9    |   1.9   |    1.9    |
|   2   | 1.89  |   1.90  |    1.90   |   1.90  |    1.90   |
|   3   | 1.899 |   1.900 |    1.900  |   1.900 |    1.900  |
Nowhere Man
  • 15,995
  • 33
  • 19
  • 29