简体   繁体   中英

Problems Generating A Math.random Number, Either 0 or 1

I want a random number, either 0 or 1 and then that will be returned to main() as in my code below.

import java.util.Scanner;
public class Exercise8Lab7 {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int numFlips = 0;
        int heads = 0;
        int tails = 0;
        String answer;


        System.out.print("Please Enter The Number Of Coin Tosses You Want: ");
        numFlips = input.nextInt();

        for(int x = 1;x <= numFlips; x++){
            if(coinToss() == 1){
                answer = "Tails";
                tails++;
            }
            else{
                answer = "Heads";
                heads++;
            }
            System.out.print("\nCoin Toss " + x + ": " + answer);
        }
        System.out.println("\n\n====== Overall Results ======" +
        "\nPercentage Of Heads: " + (heads/numFlips)*100 + "\nPercentage Of Tails: " + (tails/numFlips)*100);
    }

    public static int coinToss(){
        double rAsFloat = 1 * (2 + Math.random( ) );
        int r = (int)rAsFloat;
        return r;
    }
}

Many solutions had been suggested to use the util.Random option which I have done and works perfectly but I want to sort out why I can't get this to work. Obviously I want the number to be an int myself so I convert it to an int after the random number has been generated. But no matter what I add or multiply the Math.random() by, it will always all either be Heads or all either be Tails. Never mixed.

You could use boolean values of 0 or 1 based on value of Math.random() as a double between 0.0 and 1.0 and make the random generator much simpler. And you can get rid completely of the coinToss() method.

if(Math.random() < 0.5) {
    answer = "Tails";
    tails++;
}

Remove the coin toss method and replace the first conditional with the code above.

Math.random(); by itself will return a value between 0.0 and less than 1.0. If the value is in the lower half, [0.0, 0.5), then it has the same probability of being in the upper half, [0.5, 1.0). Therefore you can set any value in the lower half as true and upper as false.

试试这个)它会生成数字01

 Math.round( Math.random() )  ;

Wierd that no one is using a modulo division for the random number. This is the simplest implementation you can get:

Random rand = new Random();
int randomValue = rand.nextInt() % 2;

Math.round(Math.random()) will return either 0.0 and 1.0. Since both these values are well within the limits of int range they can be casted to int.

public static int coinToss(){
    return (int)Math.round(Math.random());
}

(int)(Math.random()*2) 在这种情况下也能正常工作

its not working because of the integer math you are using, the call to 2+ Math.Random is pretty much always giving you a answer between 0.0 and 1.0.

so assuming that you recieve 0.25 as your result your maths is as follows

double d = 1* (2 + 0.25); // (result = 2  

Then you are checking to see if your result == 1 ( which it never will. )

A better result would be to declare java.util.Random as a class variable and call random.nextBoolean() and simply perform your heads/tails calculation on that.

If you were to continue to use Math.random() and lets say

return Math.random() < 0.5

Your results would be ever so slightly skewed due to the fact that Math.random() cannot return 1.0, due to the fact that the java API specification states:

"Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0."

Math.random() returns a random float in the range [0.0,1.0)--that means the result can be anything from 0 up to but not including 1.0.

Your code

double rAsFloat = 1 * (2 + Math.random( ) );

will take this number in the [0.0,1.0) range; adding 2 to it gives you a number in the [2.0,3.0) range; multiplying it by 1 does nothing useful; then, when you truncate it to an integer, the result is always 2.

To get integers from this kind of random function, you need to figure out how many different integers you could return, then multiply your random number by that. If you want a "0 or 1" answer, your range is 2 different integers, so multiply Math.random() by 2:

double rAsFloat = 2 * Math.random();

This gives you a random number in the range [0.0,2.0), which can then be 0 or 1 when you truncate to an integer with (int) . If, instead, you wanted something that returns 1 or 2, for example, you'd just add 1 to it:

double rAsFloat = 1 + 2 * Math.random();

I think you've already figured out that the Random class gives you what you want a lot more easily. I've decided to explain all this anyway, because someday you might work on a legacy system in some old language where you really do need to work with a [0.0,1.0) random value. (OK, maybe that's not too likely any more, but who knows.)

The problem can be translated to boolean generation as follow :

public static byte get0Or1 {

Random random = new Random();
boolean res=   random.nextBoolean();

if(res)return 1;
else return 0;

}
 for(int i=0;i<100;i++){
System.out.println(((int)(i*Math.random())%2)); 
    }

use mod it will help you!

Here it the easiest way I found without using java.util.Random.

Blockquote

Scanner input = new Scanner (System.in);

System.out.println("Please enter 0 for heads or 1 for tails");

int integer = input.nextInt();

input.close();

int random = (int) (Math.random() + 0.5);

if (random == integer) {
    System.out.println("correct");
}
else {
    System.out.println("incorrect");
}
System.out.println(random);

This will take a random double from (0 to .99) and add .5 to make it (.5 to 1.49). It will also cast it to an int, which will make it (0 to 1). The last line is for testing.

One more variant

rand.nextInt(2);

As it described in docs it will return random int value between 0 (inclusive) and the specified value (exclusive)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM