Каков наилучший способ создания случайного значения float, включенного в указанный интервал значений?

Я хочу создать случайное значение float в Java. Значение должно быть в пределах определенного диапазона возможных значений.

Например, мне нужно создать случайное значение, находящееся в следующем диапазоне:

MIN: 41,815080
MAX: 41,829191

Эти значения представляют собой диапазон возможных долгот на карте, но вопрос применяется в целом.

Что такое умный способ сделать это?

Ответ 1

Для случайного значения в пределах диапазона формула:

double random = min + Math.random() * (max - min);

Эта базовая формула постоянна независимо от того, что вы используете для генерации случайных чисел.

Math.random() обеспечивает умеренно хорошо распределенные номера, но вы можете заменить его любым генератором случайных чисел, который вы хотите, например (немного лучше):

Random r = new Random();
double random = min + r.nextDouble() * (max - min);

или если вы действительно хотите float:

float random = min + r.nextFloat() * (max - min);

Или вы можете более экзотическую стороннюю библиотеку.

Ответ 2

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

import java.util.Random;

public static float randFloat(float min, float max) {

    Random rand = new Random();

    return rand.nextFloat() * (max - min) + min;

}

Надеюсь, это помогло.

Ответ 3

Код:

import java.util.Scanner;


public class Hello 
{

    public static void main(String[] args)
    {       

        Scanner sc=new Scanner(System.in);

        double max,min,randfloat;

        System.out.println("Enter minimum :");
        min=sc.nextDouble();
        System.out.println("Enter maximum :");
        max=sc.nextDouble();    

        randfloat=(Math.random())*(max-min)+min; //Math.random() generates random value between 0 and 1

        System.out.println("Random float value generated is: "+randfloat);
        sc.close();

    }

}

Example

Ответ 4

Я знаю, что этому вопросу больше года, но в других ответах здесь не хватает важных моментов. Лучший способ для генерации случайного значения с плавающей точкой в Java (при условии, что вам не нужно определенное начальное число и вам не нужно быть криптографически безопасным) - это класс ThreadLocalRandom.

Например, если вам нужен метод, который генерирует случайные числа между двумя другими числами, вы можете написать его так:

public static double generateRandomDouble(double min, double max) {
  return ThreadLocalRandom.current().nextDouble(min, max);
}
  • Проблема с Math.random заключается в том, что это приводит к конфликту. Другими словами, если ваш код выполняется одновременно с любым другим кодом, который использует Math.random, ваше случайное число, возможно, придется пересчитать.
  • Проблема с new Random() заключается в том, что он создает новый экземпляр Random каждый раз, когда вызывается, что является дополнительной работой и более многословным.
  • Проблема обоих этих методов заключается в том, что они заставляют вас делать дополнительные математические вычисления, чтобы масштабировать их до желаемого диапазона, делая ваш код менее читаемым и более подверженным ошибкам. Класс ThreadLocalRandom имеет очень удобную перегрузку nextDouble которая позволяет вам указывать "origin" и "bound", то есть минимум и максимум.
  • Другая проблема с обоими этими методами заключается в том, что они неточные. Поскольку вы выполняете масштабирование, вам необходимо учитывать проблемы округления, присущие арифметике с плавающей точкой. На самом деле, все остальные ответы на этот вопрос иногда дают ответы, равные макс.

В приведенном выше коде я делаю два предположения. Во-первых, вы хотите, чтобы нижняя граница была включающей, а верхняя - исключительной. Это предположение довольно тривиально, потому что вероятность фактической посадки на границе очень мала. Это также то, что пытаются сделать другие ответы (хотя иногда они дают ответы, равные max, в отличие от моих). Второе предположение, которое я делаю, заключается в том, что под "случайным значением с плавающей запятой" вы подразумеваете значение с плавающей запятой, которое я принял на основании того факта, что вы пометили вопрос с помощью . Таким образом, я дал метод, который возвращает значение double, представляющее собой значение с плавающей запятой двойной точности, и то, что вы обычно будете использовать в Java для значений с плавающей запятой. Однако, если вы хотели указать примитив с float, вы можете использовать следующий метод:

public static float generateRandomFloat(float min, float max) {
  if (min >= max)
    throw new IllegalArgumentException("max must be greater than min");
  float result = ThreadLocalRandom.current().nextFloat() * (max - min) + min;
  if (result >= max) // correct for rounding
    result = Float.intBitsToFloat(Float.floatToIntBits(max) - 1);
  return result;
}

К сожалению, перегрузка nextFloat в ThreadLocalRandom, возможно потому, что они ожидают, что очень немногие люди будут нуждаться в случайных float с float. Чтобы правильно написать этот метод, необходимо исправить ошибки округления с плавающей точкой. Таким образом, я настоятельно рекомендую вам использовать версию, которая производит double.

В заключение, вы никогда не должны использовать Math.random и не должны создавать новый экземпляр Random каждый раз, когда вам нужно сгенерировать случайное число (если, конечно, вам не нужен конкретный начальный номер). При генерации случайных чисел по умолчанию используется класс ThreadLocalRandom.