Генерировать случайное поплавок между ними как с min & amp; max включительно в JavaScript [дубликат]

Попробуйте следующее:

directionsDisplay.setMap(null);

Здесь вы можете увидеть пример кода http://code.google.com/apis/maps/documentation/javascript/examples/directions-simple. HTML

12
задан Will Vousden 27 January 2010 в 01:33
поделиться

7 ответов

Не важно ли это, включая границы, действительно, строго говоря, то, что вы пытаетесь сделать, на самом деле не имеет смысла. Помните, что при непрерывном распределении вероятности вероятность получения определенного значения бесконечно мала, так что математически говоря, вы никогда не увидите точного значения 1.

Конечно, в мире компьютеров, распределение RNG не является по-настоящему непрерывным, так что «возможно», что вы столкнетесь с определенным значением (независимо от того, что это означает), но тот факт, что вы полагаетесь на ограничение того, как хранятся реальные числа, намекает на проблемы с вашим подходом к любой проблеме, которую вы пытаетесь решить.

8
ответ дан Will Vousden 17 August 2018 в 21:15
поделиться
  • 1
    Спасибо за ваш ответ. Я думаю, что это просто плохо сформированное упражнение, которое я делаю. Упражнение состоит в том, чтобы написать свой собственный объект Math случайным методом, который принимает значения min, max и inclusive в качестве аргументов. Инклюзивный аргумент является логическим, который говорит, хотите ли вы, чтобы набор был инклюзивным или эксклюзивным. Теперь, когда я указал в своем первоначальном вопросе, что функция Math.random () не является исчерпывающей или эксклюзивной, поскольку она включает 0, но исключает 1. Таким образом, чтобы написать случайный метод, который действительно включен, или эксклюзивный и равномерно распределенный, невозможно, правильно ? – Adrian Adkison 27 January 2010 в 01:42
  • 2
    Это невозможно, так как на самом деле существует только конечное число значений, которые могут генерироваться RNG между 0 и 1 (а не континуумом). Это, однако, математически бессмысленно. Либо упражнение ссылается конкретно на целые числа, либо на плохой вопрос. Кроме того, расширение дискретного равномерного распределения для формирования другого равномерного распределения является нетривиальным. Решения Тревора и Брайана МакКенны очень близки, но не совсем однородны. – Will Vousden 27 January 2010 в 01:48

Приложение:

Взглянув на исходный код java.util.Random, включенный в дистрибутив Oracle JDK 7 ( "Copyright (c) 1995, 2010, Oracle и / или его филиалы. ) показывает этот простой код:

class Random {

    public float nextFloat() {
        return next(24) / ((float)(1 << 24));
    }

    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48 - bits));
    }
}

Таким образом, для nextFloat():

  1. Возьмите «случайное целочисленное значение» между 0 и 2 ^ 24-1 (точнее, случайный 24-битный битпаттерн, интерпретируемый как целочисленное значение),
  2. Преобразуйте его в float (в Java, «float» является 32-битной плавающей точкой IEEE 724, которая может представлять до 2 ^ 24 без потери точности, и таким образом это будет значение от 0 до 1,6777215E7)
  3. Затем разделим его на float-представление 2 ^ 24, снова просто представим без потери точности, как 1.6777216E7. 2 ^ 24 + 1 = 16777217 упадет до 1,6777216E7, когда будет вынуждено плавать. В коде это действительно должно быть константой. Эй, Солнце, циклы не растут на деревьях!
  4. Подразделение приводит к поплавке в [0.0 .. 0.99999994] (правильный результат разделения будет около 0.999999940395355224609375), с, я думаю, все возможное Значения с плавающей запятой IEEE 724 между «одинаково возможными».

См. Также Плавающая точка IEEE и Арифметика с плавающей запятой на JVM .

Комментарии Javadoc для `next ():

/**
 * Generates the next pseudorandom number. Subclasses should
 * override this, as this is used by all other methods.
 *
 * <p>The general contract of {@code next} is that it returns an
 * {@code int} value and if the argument {@code bits} is between
 * {@code 1} and {@code 32} (inclusive), then that many low-order
 * bits of the returned value will be (approximately) independently
 * chosen bit values, each of which is (approximately) equally
 * likely to be {@code 0} or {@code 1}. The method {@code next} is
 * implemented by class {@code Random} by atomically updating the seed to
 *  <pre>{@code (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)}</pre>
 * and returning
 *  <pre>{@code (int)(seed >>> (48 - bits))}.</pre>
 *
 * This is a linear congruential pseudorandom number generator, as
 * defined by D. H. Lehmer and described by Donald E. Knuth in
 * <i>The Art of Computer Programming,</i> Volume 3:
 * <i>Seminumerical Algorithms</i>, section 3.2.1.
 *
 * @param  bits random bits
 * @return the next pseudorandom value from this random number
 *         generator's sequence
 * @since  1.1
 */

Комментарии Javadoc для nextFloat():

/**
 * Returns the next pseudorandom, uniformly distributed {@code float}
 * value between {@code 0.0} and {@code 1.0} from this random
 * number generator's sequence.
 *
 * <p>The general contract of {@code nextFloat} is that one
 * {@code float} value, chosen (approximately) uniformly from the
 * range {@code 0.0f} (inclusive) to {@code 1.0f} (exclusive), is
 * pseudorandomly generated and returned. All 2<font
 * size="-1"><sup>24</sup></font> possible {@code float} values
 * of the form <i>m&nbsp;x&nbsp</i>2<font
 * size="-1"><sup>-24</sup></font>, where <i>m</i> is a positive
 * integer less than 2<font size="-1"><sup>24</sup> </font>, are
 * produced with (approximately) equal probability.
 *
 * <p>The method {@code nextFloat} is implemented by class {@code Random}
 * as if by:
 *  <pre> {@code
 * public float nextFloat() {
 *   return next(24) / ((float)(1 << 24));
 * }}</pre>
 *
 * <p>The hedge "approximately" is used in the foregoing description only
 * because the next method is only approximately an unbiased source of
 * independently chosen bits. If it were a perfect source of randomly
 * chosen bits, then the algorithm shown would choose {@code float}
 * values from the stated range with perfect uniformity.<p>
 * [In early versions of Java, the result was incorrectly calculated as:
 *  <pre> {@code
 *   return next(30) / ((float)(1 << 30));}</pre>
 * This might seem to be equivalent, if not better, but in fact it
 * introduced a slight nonuniformity because of the bias in the rounding
 * of floating-point numbers: it was slightly more likely that the
 * low-order bit of the significand would be 0 than that it would be 1.]
 *
 * @return the next pseudorandom, uniformly distributed {@code float}
 *         value between {@code 0.0} and {@code 1.0} from this
 *         random number generator's sequence
 */
0
ответ дан David Tonhofer 17 August 2018 в 21:15
поделиться

Функция Math.random возвращает случайное число от 0 до 1, где 0 включено и 1 является исключительным. Это означает, что единственный способ правильно распределить случайные числа в виде целых чисел в интервале - использовать эксклюзивный верхний предел.

Чтобы указать инклюзивный верхний предел, вы просто добавляете его к нему, чтобы сделать его эксклюзивным в расчет. Это будет правильно распределять случайные числа между 7 и 12, включительно:

var min = 7;
var max = 12;
var rnd = min + Math.floor(Math.random() * (max - min + 1));
6
ответ дан Guffa 17 August 2018 в 21:15
поделиться
  • 1
    +1 Для классического подхода к определению произвольного случайного диапазона – Justin Johnson 27 January 2010 в 03:45

Вы хотите, чтобы он включал 1?

return 1 - Math.random();

Однако, я думаю, что это один из тех вопросов, который намекает на другие проблемы. Зачем вам нужно включить 1? Вероятно, есть лучший способ сделать это.

3
ответ дан nickf 17 August 2018 в 21:15
поделиться
  • 1
    Но он не будет включать 0 – Trevor 27 January 2010 в 01:32
  • 2
    это было бы теперь эксклюзивным сейчас .. не так ли? – Gabriele Petrioli 27 January 2010 в 01:32
  • 3
    Да, но он не сказал, что исключение 0 было проблемой, только это исключало 1. – John Knoeller 27 January 2010 в 01:47

Из того, что я вижу из консоли JavaScript в Chrome, Math.random() генерирует число от 0 до 0.9999999999999999. Принимая это во внимание, вы можете получить то, что хотите, добавив модификатор. Например, вот функция, которая даст вам квази-случайное поплавок между 0 и 1, при этом 1 включительно:

function randFloat() {
  // Assume random() returns 0 up to 0.9999999999999999
  return Math.random()*(1+2.5e-16);
}

Вы можете попробовать это в консоли, нажав 0.9999999999999999*(1+2.5e-16) - он будет верните ровно 1. Вы можете принять это дальше и вернуть поплавок между 0 и 1024 (включительно) с помощью этой функции:

function randFloat(nMax) {
  // Assume random() returns 0 up to 0.9999999999999999
  // nMax should be a float in the range 1-1024
  var nMod;
  if (nMax<4) nMod = 2.5e-16;
  else if (nMax<16) nMod = 1e-15;
  else if (nMax<32) nMod = 3.5e-15;
  else if (nMax<128) nMod = 1e-14;
  else if (nMax<512) nMod = 3.5e-14;
  else if (nMax<1024) nMod = 1e-13;
  return Math.random()*(nMax+nMod);
}

Вероятно, есть более эффективный алгоритм.

0
ответ дан thdoan 17 August 2018 в 21:15
поделиться

Поскольку этот вопрос снова задан, и я не читал этот подход, здесь я добавлю еще один ответ.

IMO, что вы можете сделать, без особых проблем:

exclusive:

//simply ignore the 0
for(var rand=0; !rand;rand = Math.random());

//or simpler:
var rand = Math.random() || Math.random();
//because the probability for two consecutive `0` is pretty much non existant.

это даже не приводит к ошибке, так как мы просто исключили возможность возврата 0, каждое другое значение между 0 и 1 имеет ту же вероятность

включительно:

var rand = Math.random() * 2;
if(rand > 1) rand-=1;
//so the 0 shares it's probability with the 1.

просто чтобы понять, насколько крошечной является «ошибка»:

  • вероятность для 0 или 1 - 1 / Math.pow(2, 54) или 5.55e-17
  • , вероятность любого другого значения между 0 и 1 равна 1 / Math.pow(2, 53) или около 11.1e-17

, и вся случайная функция будет:

function random(min, max, inclusive){
    var r = Math.random();
    if(inclusive)
        r = r>0.5? 2*r-1: 2*r;
    else 
        while(!r) r = Math.random();

    return r * (max - min) + min;
}

Редактирование: я не уверен, что я ошибаюсь, но не следует полагаться на инклюзивный подход, если я добавьте еще один бит в нули и единицы и, следовательно, продублируйте их вероятность:

var rand = Math.random() * 4;
rand = (rand % 1) || (rand & 1);
0
ответ дан Thomas 17 August 2018 в 21:15
поделиться

Это вернет [0,1] включительно:

if(MATH.random() == 0)
    return 1;
else
    return MATH.random();

Объяснение: Если первый вызов random () возвращает 0, верните 1. В противном случае снова вызовите случайный случай, который будет [0 , 1). Поэтому он будет возвращать [0,1] все включено.

11
ответ дан Trevor 17 August 2018 в 21:15
поделиться
  • 1
    почему случайный дважды. что, если вы все равно получите 0 ... – bryantsai 27 January 2010 в 01:31
  • 2
    Это также не будет включать 0, как вы упомянули в своем комментарии к nickf – Gabriele Petrioli 27 January 2010 в 01:33
  • 3
    Если первый случайный () вызов не равен 0, может быть вызван второй случайный () вызов. – Trevor 27 January 2010 в 01:35
  • 4
    Наверное, сложно сказать, что униформу, но +1 за то, что ты вернулся. – bryantsai 27 January 2010 в 01:38
  • 5
    Это не совсем однородно, но близко . – Will Vousden 27 January 2010 в 01:42
Другие вопросы по тегам:

Похожие вопросы: