Как генерировать случайные числа, которые обеспечат правильные результаты при делении - PullRequest
5 голосов
/ 13 мая 2011

Как генерировать случайные числа, которые обеспечат надлежащие результаты при делении (т. Е. Результаты должны округляться ровно на 1 или 2 места после десятичной точки).

(например, целое число с десятичным числом, обеспечивающее десятичное числорезультаты - ниже я привел набор примеров входных данных)

2827 by 2.5 = 1130.8
1747 by 0.8 = 2183.75
425 by 0.4 = 1062.5
935 by 0.8 = 1168.75

Ответы [ 5 ]

4 голосов
/ 13 мая 2011
res = input * random.nextInt (100) / 100.0;

Пояснение:

Вы берете целое число n и умножаете его на что-то. Если это число типа 34.56, мы называем часть перед десятичной цифрой w (целую часть), а часть за .xy.

Если вы умножите это на n, вы получите (n * w) + (n * (x / 10)) + n * (y / 100). За точкой никогда не будет дробных цифр части 3 - вы согласны?

Мы можем объединить x и y в одну часть и сказать (n * w) + (n * (xy / 100)), а xy - это просто имя от 0 до 100.

Поскольку часть перед десятичной точкой может быть произвольно большой, вы можете рассчитать ее отдельно, если вам нужно что-то еще, кроме 0. Но вы должны как-то определить диапазон. Если вы берете случайное целое число R для этой части:

res = input * R * random.nextInt (100) / 100.0;

Вам нужен дивизор explicityl?

div = 100.0 / (R * random.nextInt (100));

Scala всегда удобен при тестировании фрагмента кода:

val r = util.Random 
r: util.Random.type = scala.util.Random$@ce2f12

scala> def res (input: Int) = input * r.nextInt (100) / 100.0;
res: (input: Int)Double

scala> (1 to 20).map (res) 
res338: scala.collection.immutable.IndexedSeq[Double] =
Vector(0.48, 1.58, 0.48, 2.8, 0.15, 1.98, 5.67, 3.36, 6.93, 6.0, 9.02, 0.48, 7.41, 6.44, 9.6, 1.92, 16.66, 5.94, 7.98, 18.4)
3 голосов
/ 13 мая 2011

Стоит отметить, что все целые числа можно разделить на 0,4, 0,8 или 2,5 и представить в виде двух десятичных знаков. Это потому, что это то же самое, что умножение на 2,5, 1,25 и 0,4


Однако, если у вас есть делитель, для которого это не так, вы можете сделать это в цикле.

double divisor = 2.4;
double factor = 100/divisor;
Random rand = new Random();
int maxValue = 1000;
double ERROR = 1e-14*maxValue;

for(int i=0;i<100;i++) {
long randNum;
do {
   randNum = rand.nextInt(maxValue+1);
    if (Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR)
        System.out.println("reject "+randNum + " => "+randNum/divisor);
} while(Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR);
System.out.println(randNum + " => "+randNum/divisor);

печать

729 => 303.75
285 => 118.75
84 => 35.0
123 => 51.25
999 => 416.25
75 => 31.25
reject 727 => 302.9166666666667
reject 842 => 350.83333333333337
504 => 210.0
reject 368 => 153.33333333333334
441 => 183.75
579 => 241.25
165 => 68.75

Это будет генерировать случайные числа, пока у вас не будет числа, кратного 0,01.

1 голос
/ 13 мая 2011

Если вы хотите, чтобы результат «округлялся» до 2 десятичных разрядов (на самом деле это не округление, это просто конечное десятичное представление с двумя десятичными точками), просто сгенерируйте делитель, и дивиденд всегда будет равен 100, например:

 106250 / 100 = 1062.5
 116875 / 100 = 1168.75

Если вы хотите более интересные дивиденды, то разделите делитель и дивиденд. например первый может быть любым из:

 (/1):   106250 / 100 = 1062.5
 (/2):   53125 / 50 = 1062.5
 (/10):  10625 / 10 = 1062.5
 (/4):   26562.5 / 25 = 1062.5
 (/125): 850 / 0.8 = 1062.5
0 голосов
/ 12 июня 2011

Используйте setRoundingMode, чтобы установить режим округления, затем используйте шаблон формата для требуемого вывода.

Проверьте это post ....

0 голосов
/ 08 июня 2011

Для меня дивиденд и делитель - это случайные числа.Я должен дать ответ, который не требует округления десятичных знаков после 2 десятичных знаков.

Если это так, ответ может быть «такого числа нет».Вот небольшая Java-программа, которую я написал для проверки этой гипотезы:

import java.text.DecimalFormat;

public class Test {
    public static void main(String[] args) {
        double num = Math.PI;
        DecimalFormat format = new DecimalFormat(
                "####################################0." +
                "00##############################");
        while (true) {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                double tmp = (i / num) * 100;
                if (tmp == (long) tmp) {
                    System.err.println("Solution - " + i + " - " + 
                            format.format(tmp) + " - " + format.format(num));
                    break;
                }
            }
            pi = Math.nextAfter(num, 1);
        }
        System.err.println("No solution for " + format.format(num));
    }
}

Я запустил ее в течение 10 минут (начиная с PI) и не нашел значений num, которые не имели бы решения i.Но я заметил, что решения могут быть очень редкими.Например:

Gotcha! - 179453441 - 5712180438.00 - 3.1415926535897714

Потребовалось 179 миллионов попыток найти решение для этого делителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...