C#十进制转八进制

C# Decimal To Octal

有很多问题,但我似乎无法在答案中找到原因。通常是:不,用这个替换这个或者这个应该可以工作。

我的任务是创建一个程序,要求用户输入一个 3 位正整数(十进制),然后将其转换为八进制。

例如,在纸上:将数字112转换为八进制。 (8 是八进制的基数。)

这些是您要采取的步骤:

从下往上的余数是十进制表示112的八进制数。 所以112的八进制数是160.

我在互联网上找到了以下程序,但我并不完全理解它。 程序中的评论是我的。谁能给我解释一下吗?

        //declaration and initialization of variables but why is there an array?
        int decimalNumber, quotient, i = 1, j;
        int[] octalNumber = new int[100];

        //input
        Console.WriteLine("Enter a Decimal Number :");
        decimalNumber = int.Parse(Console.ReadLine());

        quotient = decimalNumber;

        //as long as quotient is not equal to 0, statement will run
        while (quotient != 0)
        {
            //this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
            octalNumber[i++] = quotient % 8;
            //divide the number given by the user with the octal base number
            quotient = quotient / 8;
        }
        Console.Write("Equivalent Octal Number is ");
        //i don't understand the code below here aswell. 
        for (j = i - 1; j > 0; j--)
            Console.Write(octalNumber[j]);
        Console.Read();

非常感谢任何帮助。

这已经内置到 .NET 中,Convert.ToString 已经做到了。

在您的代码中,在您拥有 decimalNumber = int.Parse(...) 之后,您可以这样做:

Console.WriteLine(Convert.ToString(decimalNumber, 8));
Console.Read();

然后删除其余代码。

现在,如果您问的不是如何在 .NET 中进行八进制转换,而是询问代码的实际工作原理,那么它的工作原理如下:

这个循环完成了繁重的工作:

1   while (quotient != 0)
    {
        //this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
2       octalNumber[i++] = quotient % 8;
        //divide the number given by the user with the octal base number
3       quotient = quotient / 8;
    }

我在行中添加了一些数字,以便更容易编写描述。

基本上,循环就是这样做的(上面的行对应下面的点)。

  1. 只要我们有一个数字要转换(也就是说。我们还没有完成),循环。
  2. 找出最低有效位,这是除以8后的余数,由remainder operator%处理,将此位存储到数组的下一个位置。
  3. 除以 8 去掉最低有效位并将所有其他数字向上移动一位

然后循环回来。

但是,由于我们基本上找到了从最右边到左边的所有数字,所以最后的循环以相反的顺序将它们写回。

作为 reader 的练习,尝试找出问题中代码的行为方式,如果您:

  • 输入一个负数
  • 输入 0

(提示,它的行为不正确,但 Convert.ToString 正确)

使用数组是因为它们在 while 循环的每次交互中计算每个数字。 (例如){0, 6, 1}

程序的最后一部分是打印出每个数字,从数组中的最后一项开始,然后移动到第一项。在这种情况下,它会打印出: 160

首先要理解的是:这是解决这个问题的糟糕方法。代码中充满了奇怪的选择;看起来有人对这个问题采取了糟糕的 C 解决方案并将其转换为 C# 而没有经过仔细思考或使用良好实践。如果你想学习如何理解你在互联网上找到的蹩脚代码,这是一个很好的例子。如果您正在尝试学习如何设计好的代码,这是一个很好的例子,说明了不该做什么。

//declaration and initialization of variables but why is there an array?

有一个数组,因为我们希望存储所有八进制数字,而数组是一种存储多个相同类型数据的便捷机制。

但我们可以在这里问一些更相关的问题:

  • 为什么是 100 码?这没有错,但这比必要的要大得多。是什么思维过程导致了 100 个被选中?为什么那个思考过程没有在任何地方记录下来?
  • 为什么是 int 数组?我们正在输出文本,这是一个字符序列。有一堆字符似乎更自然。
  • 为什么是数组?由于我们正在构建先进后出的数据结构,因此堆栈似乎更合适。或者为什么不简单地累积一个字符串?如果字符串很大,那是低效的,但是来自 32 位整数的八进制字符串永远不会很大!
  • 为什么程序会向控制台产生输出?一个更好的分解程序肯定会有一个方法,它接受一个 int 和 returns 一个八进制字符串,然后可以打印它。
  • 为什么有些变量的名称是描述性的,而有些变量的名称是非描述性的?代码的作者是不是故意要混淆reader?还是他们根本没有仔细考虑?
  • 为什么 i - 显然是数组中的当前索引 - 从 1 开始?!这简直匪夷所思。在 C# 中,数组从零开始。
  • 如果您输入负数会怎样?试试吧!
  • 如果输入零会怎样?

然后我们继续:

decimalNumber = int.Parse(Console.ReadLine());

此代码假定输入的文本是合法的整数,但不能保证。所以这个程序可能会崩溃。 TryParse应该使用,故障模式应该处理

 // this is how the remainder is calculated but it is 
 // then put in an array + 1, i don't understand this.
 octalNumber[i++] = quotient % 8;

代码的作者认为他们很聪明。这太聪明了。将您脑海中的代码重写为最初应该如何实现的代码。首先,将 i 重命名为 currentIndex。接下来,每个语句产生 one 副作用,而不是 two:

    while (quotient != 0)
    {
        octalNumber[currentIndex] = quotient % 8;
        currentIndex += 1;
        quotient = quotient / 8;
    }

现在应该清楚是怎么回事了。

 // I don't understand the code below here as well. 
 for (j = i - 1; j > 0; j--)
   Console.Write(octalNumber[j]);

举个小例子。假设这个数是14,八进制就是16。第一次通过循环,我们将 6 放入槽 1。下一次,我们将 1 放入槽 2。因此数组为 {0, 6, 1, 0, 0, 0, 0 ... }i 为 3。我们希望输出 16 .所以我们从 i-1 循环 j 到 1,然后打印出 1 然后 6.

那么,为您练习:再次编写此程序,这次使用精心设计的 C# 程序的约定。将您的尝试放在代码审查网站上,人们会很乐意为您提供改进建议。