【问题标题】:Problems Generating A Math.random Number, Either 0 or 1生成数学随机数(0 或 1)的问题
【发布时间】:2015-02-09 00:30:09
【问题描述】:

我想要一个随机数,0 或 1,然后将其返回给 main(),如下面的代码所示。

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

许多解决方案都被建议使用 util.Random 选项,我已经完成并且效果很好,但我想弄清楚为什么我不能让它工作。显然我希望这个数字自己是一个 int,所以我在生成随机数后将它转换为一个 int。但无论我添加或乘以 Math.random(),它总是要么是 Heads,要么都是 Tails。从来不混。

【问题讨论】:

  • 好吧,写 1 * 应该是你没有做对的线索,因为任何东西乘以 1 并不能完成很多事情。
  • Random.nextInt() 版本采用上限。否则,好吧,只需生成一个随机 int 并对其执行% 2
  • 因为Math.random() + 2 会生成一个介于 2.0 和 2.9 之间的随机数。此范围内的任何内容都不会等于 1。如果您只对 0 或 1 感兴趣,请使用 Math.round(Math.random())
  • 感谢所有回答的人!我只是将 Math.random() 乘以 2,现在它给了我正面和反面的随机答案。现在的问题是最后一个打印语句中 Heads 的百分比和 Tails 的百分比根本不起作用,它们总是 = 0...

标签: java random


【解决方案1】:

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

 Math.round( Math.random() )  ;

【讨论】:

  • 不鼓励使用纯代码和“试试这个”的答案。
  • 这将产生双倍值。示例:1.0
【解决方案2】:

您可以使用基于 Math.random() 的布尔值 0 或 1 作为 0.0 和 1.0 之间的双精度值,并使随机生成器更简单。并且可以完全摆脱coinToss() 方法。

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

去掉抛硬币的方法,把第一个条件替换成上面的代码。

Math.random(); 本身将返回一个介于 0.0 和小于 1.0 之间的值。如果该值在下半部分,[0.0, 0.5),那么它有相同的概率在上半部分,[0.5, 1.0)。因此,您可以将下半部分的任何值设置为真,上半部分为假。

【讨论】:

    【解决方案3】:

    奇怪的是,没有人对随机数使用模除法。 这是您可以获得的最简单的实现:

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

    【讨论】:

      【解决方案4】:

      Math.round(Math.random()) 将返回 0.0 和 1.0。由于这两个值都在 int 范围的范围内,因此可以将它们强制转换为 int。

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

      【讨论】:

        【解决方案5】:

        这是我找到的不使用 java.util.Random 的最简单方法。

        块引用

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

        这将从 (0 到 .99) 中随机取一个双精度并加上 0.5 使其变为 (.5 到 1.49)。它还将它转换为一个 int,这将使它成为(0 到 1)。最后一行用于测试。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 为什么这个答案被否决了。这是几十年来已知的最好的(如果不是最好的、传播最广的)答案。
          【解决方案7】:

          由于您使用的是整数数学,它不起作用,对 2+ Math.Random 的调用几乎总是给您一个介于 0.0 和 1.0 之间的答案。

          所以假设你的结果是 0.25,你的数学如下

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

          然后您正在检查您的结果是否 == 1(它永远不会。)

          更好的结果是将 java.util.Random 声明为类变量并调用 random.nextBoolean() 并简单地对其进行正面/反面计算。

          如果您要继续使用 Math.random() 并说

          return Math.random() < 0.5
          

          由于 Java API 规范规定,Math.random() 无法返回 1.0,因此您的结果会略微偏斜:

          “返回一个带正号的双精度值,大于等于 0.0 且小于 1.0。”

          【讨论】:

          • 我认为结果不会有偏差。如果我的理解是正确的,Math.random() 可以返回的 恰好等于 >= 0.5 的可能值的数量。不过,我必须研究算法才能 100% 确定。
          • 这实际上是一个很棒的问题,而不是评论。让我们看看我是否可以将其放入评论的空间量中(并且我为缺乏格式而道歉。)以前的java版本对零有很大的偏见(函数是:((((long)next(27 )
          • at 134217728,在原始代码中,浮点数的内部尾数中最低位的偏差为 0(可能性为 3 倍),因此使用此“次要' 改变他们能够移除它,以换取对中心正上方的轻微偏差,这比在给定的固定位上有偏差要好。下一个方法也有它自己的内部偏见,这使这一点更加复杂。如果您详细检查 javadoc,它应该注意到输出“大致”一致,有两种方法可以证明这一点,第一种方法是简单地强制 -cont-
          • 2 次调用 next 和 2 次 for 循环并返回所有结果的列表(这将非常耗时),但允许您绘制结果直方图。否则,如果懒惰(并且时间有限。)创建一个循环来运行“硬币翻转”算法并计算结果,您应该注意到真假之间的比率会随着时间的推移而增长。
          • 非常有趣!当我能找到时间时,我将不得不进一步研究这个问题(一厢情愿......)。
          【解决方案8】:

          Math.random() 返回 [0.0,1.0) 范围内的随机浮点数——这意味着结果可以是从 0 到 但不包括 1.0 的任何值。

          你的代码

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

          将采用 [0.0,1.0) 范围内的数字;将 2 添加到它会给你一个 [2.0,3.0) 范围内的数字;将它乘以 1 没有任何用处;那么,当你将其截断为整数时,结果始终为 2。

          要从这种随机函数中获取整数,您需要计算出可以返回多少个不同的整数,然后将随机数乘以它。如果你想要一个“0 或 1”的答案,你的范围是 2 个不同的整数,所以将 Math.random() 乘以 2:

          double rAsFloat = 2 * Math.random();
          

          这会为您提供 [0.0,2.0) 范围内的随机数,当您使用 (int) 截断为整数时,该随机数可以是 0 或 1。相反,如果您想要返回 1 或 2 的东西,例如,您只需向其添加 1:

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

          我想你已经发现Random 类更容易为你提供你想要的东西。无论如何,我决定解释所有这些,因为有一天您可能会使用某种旧语言在遗留系统上工作,而您确实需要使用 [0.0,1.0) 随机值。 (好吧,也许这不太可能了,但谁知道呢。)

          【讨论】:

            【解决方案9】:

            问题可以转化为布尔生成如下:

            public static byte get0Or1 {
            
            Random random = new Random();
            boolean res=   random.nextBoolean();
            
            if(res)return 1;
            else return 0;
            
            }
            

            【讨论】:

              【解决方案10】:
               for(int i=0;i<100;i++){
              System.out.println(((int)(i*Math.random())%2)); 
                  }
              

              使用模组它会帮助你!

              【讨论】:

                【解决方案11】:

                另一种变体

                rand.nextInt(2);
                

                正如docs 中所述,它将返回介于 0(包括)和指定值(不包括)之间的随机 int 值

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-12-21
                  • 2014-03-02
                  • 1970-01-01
                  • 2014-04-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-22
                  相关资源
                  最近更新 更多