web-dev-qa-db-fra.com

Quel est le meilleur moyen de générer une valeur flottante aléatoire incluse dans un intervalle de valeur spécifié?

Je souhaite générer une valeur flottante aléatoire en Java. La valeur doit être comprise dans une plage spécifique de valeurs possibles.

Par exemple, je dois générer une valeur aléatoire comprise dans la plage suivante:

MIN: 41,815080
MAX: 41,829191

Ces valeurs représentent une gamme de longitudes possibles sur une carte, mais la question s’applique plus généralement.

Quelle est une façon intelligente de le faire?

12
AndreaNobili

Pour une valeur aléatoire dans une plage, la formule est la suivante:

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

Cette formule de base est constante, peu importe ce que vous utilisez pour générer des nombres aléatoires.

Math.random() fournit des nombres moyennement bien répartis, mais vous pouvez le remplacer par le générateur de nombre aléatoire souhaité, par exemple (légèrement meilleur):

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

ou si vous voulez vraiment une float:

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

Ou vous pouvez utiliser une bibliothèque tierce plus exotique. 

32
Bohemian

Si vous voulez générer des valeurs flottantes aléatoires, essayez ceci:

import Java.util.Random;

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

    Random Rand = new Random();

    float result = Rand.nextFloat() * (max - min) + min;

    return result;

}

J'espère que cela a aidé.

9
Yogesh Darji

Je sais que cette question a plus d'un an, mais les autres réponses manquent ici de points importants. Le meilleur moyen de générer une valeur aléatoire en virgule flottante en Java (en supposant que vous n'avez pas besoin d'une graine spécifique et que vous n'avez pas besoin d'être cryptographiquement sûr ) est la classe ThreadLocalRandom .

Par exemple, si vous voulez une méthode qui génère des nombres aléatoires entre deux autres nombres, vous pouvez l'écrire comme ceci:

public static double generateRandomDouble(double min, double max) {
  return ThreadLocalRandom.current().nextDouble(min, max);
}
  • Le problème avec Math.random est que il en résulte un conflit . En d'autres termes, si votre code est exécuté simultanément à tout autre code qui utilise Math.random, votre nombre aléatoire devra peut-être être recalculé.
  • Le problème avec new Random() est qu’il crée une nouvelle instance Random à chaque appel, ce qui représente un travail supplémentaire et plus prolixe.
  • Le problème avec ces deux méthodes est qu'elles forcent vous à faire le calcul supplémentaire pour le redimensionner à la plage souhaitée, rendant votre code moins lisible et plus sujet aux erreurs. La classe ThreadLocalRandom a une surcharge nextDouble très pratique qui vous permet de spécifier une "origine" et "lié", signifiant minimum et maximum.
  • Un autre problème avec ces deux méthodes est qu'elles sont imprécises. Comme vous effectuez la mise à l'échelle, vous devez prendre en compte les problèmes d'arrondis inhérents à l'arithmétique en virgule flottante. En fait, toutes les autres réponses à cette question produiront parfois des réponses égales à max.

Dans le code ci-dessus, je fais deux hypothèses. Premièrement, vous voulez que la limite inférieure soit inclusive et que la limite supérieure soit exclusive. Cette hypothèse est plutôt triviale, car la probabilité d'atterrir sur la frontière est très faible. C’est aussi ce que les autres réponses tentent de faire (bien qu’elles produisent parfois des réponses égales à max, contrairement au mien). La deuxième hypothèse que je fais est que par une "valeur flottante aléatoire", vous voulez dire une valeur à virgule flottante, ce que j'ai supposé sur la base du fait que vous avez balisé la question avec virgule flottante . Ainsi, j'ai donné une méthode qui retourne une double, qui est une valeur à virgule flottante double précision et ce que vous utiliserez généralement en Java pour les valeurs à virgule flottante. Toutefois, si vous vouliez spécifier une primitive float, vous pouvez utiliser la méthode suivante:

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;
}

Malheureusement, il n'y a pas de surcharge nextFloat sur ThreadLocalRandom, probablement parce qu'ils s'attendent à ce que très peu de personnes aient besoin de floats aléatoires. Pour écrire correctement cette méthode, vous devez corriger les problèmes d’arrondi en virgule flottante. Ainsi, je vous recommande fortement d'utiliser la version qui produit une double.

En conclusion, vous devriez jamais utiliser Math.random et vous ne devriez pas créer une nouvelle instance Random à chaque fois que vous devez générer un nombre aléatoire (à moins bien sûr que vous ayez besoin d'une graine spécifique). Lors de la génération de nombres aléatoires, utilisez par défaut la classe ThreadLocalRandom.

1
Finn

Code:

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

0
Manthan_Admane