Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

C# Decimal To Octal

There have been many questions but i can't seem to find the why in the answers. It's usually: no, replace this with this or this should work.

My task is to create a program that asks the user to input a 3 digit positive integer (decimal) that converts it to octal.

For example, on paper: To convert the number 112 to octal. (8 is the base number for octal.)

These are the steps you would take:

  • 112 / 8 = 14 remainder = 0
  • 14 / 8 = 1 remainder = 6
  • 1 / 8 = 0 remainder = 1

Remainder from bottom to up is the octal number that represents 112 in decimal. So the octal number for 112 is 160.

I found the following program on the internet but i don't understand it fully. The comments in the program are mine. Could anyone explain it to me please?

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

Any help is truly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The first thing to understand is: this is a terrible way to solve this problem. The code is full of odd choices; it looks like someone took a bad C solution of this problem and translated it to C# without applying careful thought or using good practices. If you are trying to learn how to understand crappy code you find on the internet, this is a great example. If you are trying to learn how to design good code, this is a great example of what not to do.

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

There's an array because we wish to store all the octal digits, and an array is a convenient mechanism for storing a number of data of the same type.

But we could ask some more pertinent questions here:

  • Why of size 100? It's not wrong, but that's enormously larger than necessary. What thought process led to 100 being chosen? Why wasn't that thought process documented anywhere?
  • Why an array of int? We're outputting text, which is a sequence of chars. It would seem more natural to have a bunch of chars.
  • Why an array? Since we are building a first-in-last-out data structure, a stack seems more appropriate. Or why not simply accumulate a string? That's inefficient if the string is large, but an octal string from a 32 bit integer is never large!
  • Why does the program produce output to the console? Surely a better factored program would have a method that takes an int and returns an octal string, which can then be printed.
  • Why do some of the variables have descriptive names and some have undescriptive names? Is the author of the code deliberately trying to confuse the reader? Or did they simply not think about it very carefully?
  • Why does i - apparently the current index into the array -- start at one?! This is simply bizarre. Arrays start at zero in C#.
  • What happens if you type in a negative number? Try it!
  • What happens if you type in zero?

We then go on to:

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

This code presumes that the typed-in text is a legal integer, which is not guaranteed. So this program can crash. TryParse should be used, and the failure mode should be handled.

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

The author of the code thinks they are being clever. This is too much cleverness. Rewrite the code in your head to how it should have been implemented in the first place. First, rename i to currentIndex. Next, produce one side effect per statement, not two:

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

Now it should be clear what is going on.

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

Do a little example. Suppose the number is 14, which is 16 in octal. First time through the loop we put 6 in slot 1. Next time through, we put 1 in slot 2. So the array is {0, 6, 1, 0, 0, 0, 0 ... } and i is 3. We wish to output 16. So we loop j from i-1 to 1, and print out 1 then 6.

So, exercise for you: write this program again, this time using the conventions of a well-designed C# program. Put your attempt on the code review site and people will be happy to give you tips on how to improve it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...