0

I've been doing some practice exercises on the use of the Random class.

I have a class called Card, which has five instance variables containing a reference to an integer which should sit within a specified range.

Those five numbers are being generated using the random class. Code is as follows:

public class Card
{

private String cardName;
private int yearOfInvention;
private int novelty;
private int popularity;
private double trendiness;
private int numberOfDialects;


public Card(String cardName) {
    this.cardName = cardName;
    Random rand = new Random(); 
    yearOfInvention = 1900 + rand.nextInt(111);
    novelty = rand.nextInt(10);
    popularity = rand.nextInt(100);
    trendiness = rand.nextDouble() + rand.nextInt(4);
    numberOfDialects = rand.nextInt(50);
 }

For 'trendiness', my value needs to be any digit between 0-5, including fractional parts, but only to one decimal point.

Currently it would give me e.g.

private double trendiness 1.2784547479963435

Is there a way of limiting the number of decimal points without rounding off, and impacting the 'randomness'?

javapalava
  • 711
  • 1
  • 6
  • 15

3 Answers3

3

The easiest way is probably to generate a number between 0-50, then divide by 10.

trendiness = rand.nextInt(51) / 10d;

Just don't forget to either add a descriptive comment, or extract this into a helper method with an appropriate name. Such one-liner piece of code could confuse people as it's not very clear in its intent.


EDIT answering OP's very good questions:

Why the digit between parentheses is 51 and not 50?

This is up to you to decide which is more correct. Your "digit between 0-5" spec is not very clear. The rand.nextInt(51) call will generate a random integer in the interval [0, 50]. A rand.nextInt(50) would generate a number in the interval [0, 50) (notice the half-open interval), or 0-49. You pick what's the right thing for you.

Also, what is the purpose of the d after the 10?

Let's see. Try running this:

System.out.println(new Random().nextInt(50) / 10);

It only outputs numbers 0-4. The problem is that the division is integer-based if all the numbers in the expression are integer. It will round-off any decimal remainder. To avoid that, you need to have at least one real (most often a double) number in the expression.

That's what the 10d does. It's the same as 10.0 or (double)10.

Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
1

You can use formating of decimal numbers as following

double number = 0.9999999999999; // this is eg of double no
DecimalFormat numberFormat = new DecimalFormat("#.00"); // provide info about how many decimals u want 
System.out.println(numberFormat.format(number)); 
kirti
  • 4,499
  • 4
  • 31
  • 60
0
/**
 * return a float random number between max and it's negative
 */ 
public static float getFloatRandomNumber (int max){

    double isNegative = (Math.random()*10);

    //in case it's a negative number like 50:50
    if (isNegative<=5){
        float rand = (float)((Math.random() * max));
        return Float.parseFloat(String.format("%.3f", rand));
    }

    //in case it's positive number
    float rand = (float)(((Math.random() * max)) * -1); 
    return Float.parseFloat(String.format("%.3f", rand));    
}


/**
 * return an int random number between max and it's negative
 */
public static int getIntegerRandomNumberNoZero (int maximum){

    maximum = Math.abs(maximum);

    Random rn = new Random();
    double isNegative = (Math.random()*10);

    int rand = 0;
    int range = maximum + 1;

    //getting a random number which is not zero
    while(rand == 0){
        rand =  rn.nextInt(range);

        if (isNegative<=5){
            rand = Math.abs(rand);
        }
        else {
            rand = (Math.abs(rand) * -1);
        }               
    }           

    return rand;
}
roeygol
  • 4,908
  • 9
  • 51
  • 88