【问题标题】:More Elegant Way Selecting Bit-size and Pseudo-Random Bit Generation更优雅的方式选择比特大小和伪随机比特生成
【发布时间】:2012-12-11 13:52:22
【问题描述】:

有没有比我在这里做的更优雅的方式来进行位大小选择和伪随机二进制位生成?实际上我需要编写一个算法,让用户控制生成的随机二进制位的位大小(最大 16 位)。这是我写的函数,但我不确定这是否是最小/最优雅的。由于这是科学需要,效率并不重要,但代码的优雅和易于理解确实很重要。那么有没有更有效/更优雅的方式来做同样的事情?

static string randomBit() {
    int bitSize = 0, input = 0;
    Console.Write("Input Bit Size (Maximum is 16 Bit): ");
    input = Convert.ToInt32(Console.ReadLine());
    Random choice = new Random();
    if(input == 0 || input > 16) {
        bitSize = 0;
    }
    else if(input == 1) {
        bitSize = 1;
    }
    else if(input == 2) {
        int randomChoice = choice.Next(2, 3);
        bitSize = randomChoice;
    }
    else if(input == 3) {
        int randomChoice = choice.Next(4, 7);
        bitSize = randomChoice;
    }
    else if(input == 4) {
        int randomChoice = choice.Next(8, 15);
        bitSize = randomChoice;
    }
    else if(input == 5) {
        int randomChoice = choice.Next(16, 31);
        bitSize = randomChoice;
    }
    else if(input == 6) {
        int randomChoice = choice.Next(32, 63);
        bitSize = randomChoice;
    }
    else if(input == 7) {
        int randomChoice = choice.Next(64, 127);
        bitSize = randomChoice;
    }
    else if(input == 8) {
        int randomChoice = choice.Next(128, 255);
        bitSize = randomChoice;
    }
    else if(input == 9) {
        int randomChoice = choice.Next(256, 511);
        bitSize = randomChoice;
    }
    else if(input == 10) {
        int randomChoice = choice.Next(512, 1023);
        bitSize = randomChoice;
    }
    else if(input == 11) {
        int randomChoice = choice.Next(1024, 2047);
        bitSize = randomChoice;
    }
    else if(input == 12) {
        int randomChoice = choice.Next(2047, 4095);
        bitSize = randomChoice;
    }
    else if(input == 13) {
        int randomChoice = choice.Next(4096, 8191);
        bitSize = randomChoice;
    }
    else if(input == 14) {
        int randomChoice = choice.Next(8192, 16383);
        bitSize = randomChoice;
    }
    else if(input == 15) {
        int randomChoice = choice.Next(16384, 32767);
        bitSize = randomChoice;
    }
    else if(input == 16) {
        int randomChoice = choice.Next(32768, 65535);
        bitSize = randomChoice;
    }
    string binary = Convert.ToString(bitSize, 2);
    return binary;
}

同样作为第二个问题,如果我在代码询问位大小时按 Enter 两次,它会返回异常错误。有没有办法绕过相同的?

【问题讨论】:

  • 如果位大小为 4,您为什么坚持(比如说)8 或更大的值?你基本上是通过强制最高有效位为 1 来消除一点随机性。(顺便说一下,你应该问你的第二个问题 as 第二个问题。)
  • 第二个问题也可以使用 Int32.TryParse dotnetperls.com/int-tryparse
  • @Jon Skeet 我这样做是假设 8 - 1000、9 - 1001 等等。我实际上不知道如何实现一个函数,该函数可以根据位大小(例如 4 位)用 0 填充前面的位(即不进入数组),但生成的二进制数为 2 到输出将是 0010。然而,随机性是最重要的。还有其他方法吗?
  • @Jeet.Deir:4 位的随机数应该有 16 个可能的值 - 0000 到 1111,all 值可行,而不仅仅是 1000 到 1111。

标签: c# random binary bit-manipulation


【解决方案1】:

首先,我真的认为你可以减少 if/else 语句的数量:

private static string randomBit()
{
    int bitSize = 0, input = 0;
    Console.Write("Input Bit Size (Maximum is 16 Bit): ");
    input = Convert.ToInt32(Console.ReadLine());
    Random choice = new Random();

    if (input <= 0 || input > 16)
    {
        bitSize = 0;
    }
    else if(input == 1)
    {
        bitSize = 1;
    }
    else
    {                        
        int randomChoice = choice.Next(1 << (input-1), (1 << input)-1);
        bitSize = randomChoice;
    }

    string binary = Convert.ToString(bitSize, 2);
    return binary;
}

如果您对该表达式中的左移不满意:int randomChoice = choice.Next(1 &lt;&lt; (input-1), (1 &lt;&lt; input)-1);,并且您对可读性更感兴趣,那么您可以随时将其替换为:

int randomChoice = choice.Next(Math.Pow(2, input - 1), Math.Pow(2, input) - 1);

关于异常的问题,答案是肯定的。您遇到的问题是您没有验证Convert.ToInt32 函数的输入。

你可以写而不是input = Convert.ToInt32(Console.ReadLine());

do
{
   string inputString = Console.ReadLine();
   if(!Int32.TryParse(inputString, out input))     // will return false if it can't convert
   {
       Console.WriteLine("Please enter a number between 1 and 16!");
       input = 0;
   }
}while(input == 0);

【讨论】:

  • 你能解释一下这个说法吗? else { int randomChoice = choice.Next(1 &lt;&lt; (input-1), (1 &lt;&lt; input)-1);
  • 左移运算符 (&lt;&lt;) 将向左移动变量的所有位,移动位置与右侧值指示的位置相同。在1 &lt;&lt; input 示例中,您实际上是将 0x00000001 的第 0 位移动到左侧 input 位置数 - 顺便对应于 2 的幂。您可以进一步查看(问另一个问题)或使用我在答案中显示的另一个陈述(见我的答案):)
  • 非常感谢!我真的很想了解轮班操作员。我们使用的是权力,但转变对我来说是新事物。我应该问一个新问题吗?另外,小查询,要使用 pow 函数,我不需要 double 而不是 int 吗?谢谢。
  • @Jeet.Deir - 如果您发现答案有帮助,您可以随时通过投票/标记为答案来表达您的感激之情;)至于 Math.Pow - 不,编译器将处理你。有关轮班操作员的更多信息,在进行 Google 搜索后,我建议您提出一个新问题,详细说明您想知道什么。
  • 你是最有帮助的 Miky,但我不能投票给答案,因为我有代表
猜你喜欢
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 2019-08-19
  • 2014-03-01
  • 2020-04-25
  • 2021-04-14
  • 2015-09-04
  • 2011-12-06
相关资源
最近更新 更多