如何在标签上表示二进制数?

时间:2016-05-01 14:00:36

标签: c# winforms

我将十进制转换为二进制数,但我不知道如何在标签上表示。我有一个数字0和1的列表,现在,我如何在标签上显示信息。事实上,我不知道如何在标签上代表。

   private void btnRun_Click(object sender, EventArgs e)
        {
               var decimaltoBinary = fnDecimalToBinary(Convert.ToInt32(txtenterNumber.Text));

    }

 private List<int> fnDecimalToBinary(int number)
    {

        int[] decimalNumbers = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 256 };
        List<int> binaryNumbers = new List<int>();
        int locDecimalArray = 0;
        int sumNumber = 0;

        for (int i = 0; i < decimalNumbers.Length; i++)
        {
            if (number < decimalNumbers[i])
            {
                sumNumber = number;
                locDecimalArray = i - 1;
                for (int j = locDecimalArray; j >= 0; j--)
                {
                    if (sumNumber == 0)
                    {
                        binaryNumbers.Add(0);
                        return binaryNumbers;
                    }
                    else if (sumNumber >= decimalNumbers[j])
                    {
                        sumNumber = sumNumber - decimalNumbers[j];
                        binaryNumbers.Add(1);
                    }
                    else if (sumNumber < decimalNumbers[j])
                    {
                        binaryNumbers.Add(0);
                    }
                }
                return binaryNumbers;

            }

        }
        return binaryNumbers;
    }

1 个答案:

答案 0 :(得分:3)

您似乎已收到评论,说明如何将List<int>转换为string控件所需的Label值。但是,在我看来,出于本练习的目的,您可能会受益于对十进制到二进制转换本身的一些帮助。 Stack Overflow上已经有很多类似的问题来处理这个场景(你可以猜到,转换为二进制文本是一个相当常见的编程练习),但当然没有一个会从你的特定代码开始所以我认为值得写另一个答案。 :)

基于预先计算的数值列表进行转换并不是一种可怕的方法,尤其是出于学习的目的。但是你的版本有一堆额外的代码,而这些代码并不是必需的:

  1. 除了验证传递的数字是否在预先计算的值允许的范围内之外,您的外部循环不会完成任何操作。但这可以作为转换本身的一部分来完成。
  2. 此外,我不相信返回空列表确实是处理无效输入的最佳方法。抛出异常会更合适,因为这会强制调用者处理错误,并允许您提供文本消息以显示给用户。
  3. 0始终小于您预先计算的任何数字值,因此无需明确检查。你真的只需要内环中的if和一个else
  4. 由于你是填充数组的人,并且因为for循环在0开始时通常更具可读性并且增加索引而不是从结束开始减少,所以它似乎我,你最好还是反向编写预先计算的值。
  5. 手动输入数字很痛苦,在我看来,如果允许调用者传递要生成的数字位数,并且用它来计算值,那么该方法可以更灵活(即支持更大的二进制数)在运行时(但是,如果由于性能原因不太理想,预先计算将使用的最大数字并将其存储在static字段中,然后只使用你的任何子集需要,将是另一种合适的方法)。
  6. 通过这些更改,您将获得以下内容:

    private List<int> DecimalToBinary(int number, int digitCount)
    {
        // The number can't itself have more than 32 digits, so there's
        // no point in allowing the caller to ask for more than that.
        if (digitCount < 1 || digitCount > 32)
        {
            throw new ArgumentOutOfRangeException("digitCount",
                "digitCount must be between 1 and 32, inclusive");
        }
    
        long[] digitValues = Enumerable.Range(0, digitCount)
            .Select(i => (long)Math.Pow(2, digitCount - i - 1)).ToArray();
        List<int> binaryDigits = new List<int>(digitCount);
    
        for (int i = 0; i < digitValues.Length; i++)
        {
            if (digitValues[i] <= number)
            {
                binaryDigits.Add(1);
                number = (int)(number - digitValues[i]);
            }
            else
            {
                binaryDigits.Add(0);
            }
        }
    
        if (number > 0)
        {
            throw new ArgumentOutOfRangeException("digitCount",
                "digitCount was not large number to accommodate the number");
        }
    
        return binaryDigits;
    }
    

    以下是您如何使用它的示例:

    private void button1_Click(object sender, EventArgs e)
    {
        int number;
    
        if (!int.TryParse(textBox1.Text, out number))
        {
            MessageBox.Show("Could not convert user input to an int value");
            return;
        }
    
        try
        {
            List<int> binaryDigits = DecimalToBinary(number, 8);
    
            label3.Text = string.Join("", binaryDigits);
        }
        catch (ArgumentOutOfRangeException e1)
        {
            MessageBox.Show("Exception: " + e1.Message, "Could not convert to binary");
        }
    }
    

    现在,上面的示例适合您最初的设计,只是稍微清理了一下。但事实是,计算机已经知道二进制。它是如何存储数字的,即使它没有,C#也包含将数字视为二进制的运算符(因此,如果计算机不使用二进制数,则运行时需要无论如何,为你翻译)。鉴于此,通过查看各个位,实际上转换起来要容易得多。例如:

    private List<int> DecimalToBinary2(int number, int digitCount)
    {
        if (digitCount < 1 || digitCount > 32)
        {
            throw new ArgumentOutOfRangeException("digitCount",
                "digitCount must be between 1 and 32, inclusive");
        }
    
        if (number > Math.Pow(2, digitCount) - 1)
        {
            throw new ArgumentOutOfRangeException("digitCount",
                "digitCount was not large number to accommodate the number");
        }
    
        List<int> binaryDigits = new List<int>(digitCount);
    
        for (int i = digitCount - 1; i >= 0; i--)
        {
            binaryDigits.Add((number & (1 << i)) != 0 ? 1 : 0);
        }
    
        return binaryDigits;
    }
    

    以上简单地从最高可能的二进制数字开始(给定所需的数字位数),并使用&#34;位移&#34;检查所提供数字中的每个单独数字。运算符<<和逻辑按位&#34;和&#34;运营商&。如果您还不熟悉二进制算术,移位操作和这些操作符,这可能看起来有点过分。但它实际上是计算机如何工作的一个基本方面,值得了解,当然,如上所示,可以大大简化处理二进制数据所需的代码(到参数验证代码占用方法的一半:) )。


    最后一件事:整个讨论忽略了您使用签名int值而非无符号uint类型的事实。从技术上讲,这意味着您的代码也应该能够处理负数。但是,如果您还想处理小于数字类型中数字的自然宽度的二进制数字计数(例如int的32位),这样做会有点棘手。相反,如果您不想支持负数,则应该使用uint类型而不是int

    我认为,试图解决这一特定的复杂问题会大大增加这个答案的复杂性,并从那些似乎值得传达的更基本的细节中剔除。所以我把它留了下来。但我确实鼓励您更深入地了解计算机如何表示数字,以及为什么负数需要比上述代码更谨慎的处理。