[SOLVED] Convert a number into base 8(octal) in C Program

ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Welcome to LinuxQuestions.org, a friendly and active Linux Community.

You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!

Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.

If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.

Having a problem logging in? Please visit this page to clear all LQ-related cookies.

Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.

Exclusive for LQ members, get up to 45% off per month. Click here for more info.

I was making a C program to convert a number into base 8(octal) form. I figured out how to calculate this manually on paper. The program must have an output of five digits regardless of whether the output is five digits or not. However, I have been having problems writing the code. Here is what I have come up with so far.

Code:

#include <stdio.h>
int main(void)
{
float g, h, i, j, k;
printf("Enter a number to convert into base 8: ");
scanf("%f", &g);
i = g / 8;
j = i / 8;
k = j / 8;

The program is not complete because I do not know how to continue the program. Am I supposed to assign a part of the i,j,k variables to other variables then output the new variables or is there any other method I can use?

Why are you using float variables rather than int?

To repeat an operation, learn how to use a loop or a recursive function. Using multiple variable names with straight line code may take less initial thought, but it won't help you learn to program.

If you are using int variables (not float) then the % operator in C can be convenient:

(N % 8) is the remainder you would get if you divide N by 8. That remainder is the right most digit of the base 8 representation of N.

Since 8 is a power of two, there is a simpler method of converting a number to base 8 using shift and mask, rather than divide and %.
That simpler method is especially easier in the case you described of wanting a fixed number of digits generated regardless of the input value. But if you don't already understand the relationship between binary and base 8 (that makes shift and mask work), it may be better to stick with the general method that works for any base.

The general purpose loop has the complication that it produces the digits from right to left, rather than left to right. So you would need extra work to reverse the result. That still might be the better learning path:
For an integer N: (N%8) is the last digit of its octal representation and (N/8) is the number whose octal representation consists of all but the last digit of N's octal representation.
That should tell you the general method for either a loop or a recursive function to produce the desired output.

It had not occurred to me to use the % operator, so I used the division operator and int instead of float and %. I don't know about loops very much as Selection Statements is the next chapter in my C tutorial book. Can you give me a reference for the shift and mark method?

The & operator in C used with a constant is called "masking". The number 7 has its bottom 3 bits on and all the others off, so (N&7) is the bottom three bits of N.

The >> operator in C is a right shift. For example (N>>12) throws away the bottom 12 bits of N while moving all the other bits 12 positions down.

In a loop for producing octal, you would use a variable instead of that 12, so that in each step of the loop you would move the desired bits of N into the bottom three bits to be masked.

Like %, that use of & or >> only works with int, not with float.

Even the / operator has an important difference between the way it works for int and the way it works for float. The way / works for int is convenient for use in converting a number from internal representation to a base. The way / works for float is less convenient for that purpose and requires extra work to truncate the result.

It isn't really contributing to the solution to your problem, but I would like to point out that it isn't a conversion you're doing, it is creating a particular representation of a number. The value is not changing, only the way its value is expressed. I'm not convinced that everyone who tries to deal with different number bases gets that concept. I am convinced that a lot of confusion exists about the different ways that numeric values can be expressed. Please tell me you do understand the distinction. If not, perhaps a couple of LQ blog entries I wrote will clarify things.
--- rod.

Can you post some sample input and output. I'm pretty sure you can do what you want with just printf %o and some padding. I made a C program that converts between decimal, octal, and hex, and it was simple to write, printf did all the work. As said above the number doesn't change, just the interpretation.

@johnsfine so 7 can be represented as 11100000, but could you include an example of the & and >> operator in action?
@theNbomr I think I get it the numbers themselves do not change, but they only differ in their representation. In essence 1953 is the same as 3641.

The representation of a number is primarily a human-factors thing. People read a number and derive some sort of meaning from it. Part of that meaning may be influenced by the format, or it may be that the format makes it easier or more difficult to derive the meaning. As such, there are conventions as to how we represent numbers, particularly with respect to the use of number bases (radices). One convention is that we write the digits in descending order of significance from left to right. This is only a convention, but is so widely held that I would treat it much like a rule. It is the same convention used to write in the most familiar, decimal, notation. It is also built into all text-to-number conversion software (eg scanf(), aoi(), etc.) that I've ever encountered.
When writing a representation of a number, it is a common convention to denote the number base used, especially if it is not obvious from the context. The most formal way to do so is with a subscript showing the base used for the display of the number (in decimal, always) following the number. In forums such as this, it is either difficult or impossible to produce the typography to do this, so one tends to simply use words, like

'In essence, 1953 decimal is the same as 3640 octal'.

Sometimes, it will be obvious what radix is being used, such as hexadecimal, where the digits may include the alpha characters 'A'-'F'. Also, the context may make it obvious, as some kinds of numbers are simply always represented in a particular radix. The dotted decimal IP notation would be an example of this (and there are some exceptions to this convention). I don't think many people display commonly used numbers like phone numbers or street addresses in hex, but CPU memory and IO addresses are almost always represented in hex (although it was once common to use octal for such cases).

What is not at all consistent with respect to ordering of significance is how numbers are stored in computer memory. Some CPUs store numbers with the most significant byte at the lowest memory address, while other CPUs use the opposite order. This is the basis for the terms big-endian and little-endian when used to describe byte ordering. Neither is either right or wrong, although some people seem to think so, since byte-oriented reading memory dumps for one of the cases will require some minor mental gymnastics to observe the number in its 'natural' order. That is an argument that has already occupied too much of the world's debate space.

I could probably waste even more space on the subject, but I won't. Hope this is useful.

So, you're saying that how people choose to display a number is a matter of personal choice, but it is good if people use radix. Well i'm not well versed on computer memory management, but I understand some of what you are trying to say.

So, you're saying that how people choose to display a number is a matter of personal choice, but it is good if people use radix.

Yes, sort of. To be completely pedantic, you are always using some radix to represent the number, but without saying which radix you use, the meaning of the representation can be lost or incorrect. How many apples would you have if I gave you 10?

So, you're saying that how people choose to display a number is a matter of personal choice, but it is good if people use radix. Well i'm not well versed on computer memory management, but I understand sand not going off into a ome of what you are trying to say.

Actually its about following standards. Eg:

Quote:

We normally write numbers with the bottom bits (least significant) on the right. You have them on the left.

and not seeing the woods when you should be seeing the trees (concentrating on the nitty-gritty of programming instead of going into memory management).

Just translate your manual calculation (on paper) into a programme. To start with you could even use 5 variables and just extend your programme incorporating the % operator as suggested. The hint that you are required to pad it with zeros on the left should tell that the result is a string and not a number. (If all your tutor wanted was a number, he would have taught you to use sprintf with the appropriate format string).

LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.