Decimal to octal in C - c

I have just begun teaching myself C out of K.N King's C Programming: A Modern Approach (2ndEdn).
I'm enjoying it, but am hoping to post the odd question here for advice if appropriate because unfortunately I don't have a tutor and some bits raise more questions then they answer!
I'm doing a question on taking an integer entered and displaying it in octal. It says there is an easy way to do it, but that comes later in the book. I have come up with the following:
// Convert a number to octal
int n, n2, n3, n4, n5, n6;
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
n6 = n % 8;
n5 = (n / 8) % 8;
n4 = ((n / 8) / 8) % 8;
n3 = (((n / 8) / 8) / 8) % 8;
n2 = ((((n / 8) / 8) / 8) / 8) % 8;
printf("%d%d%d%d%d", n2, n3, n4, n5, n6);
It works OK, but I'm not good at math and was wondering if there is a more efficient way of doing this or have I done it the only way possible...
If anyone else has the book it's Q4 p.71.
Thanks for your time.
Andrew
P.S I did look in the search engine but couldn't find anything that was doing it this 'slower' way!

Everyone is right in saying that there's a built-in way to do that with printf. But what about doing it yourself?
The first thing that came to mind is that one octal digit is exactly three bits. Therefore you can do the conversion this way:
Loop while n != 0
Isolate the leftmost 3 bits of n into d and print d
Shift n 3 bits to the left
The code is trivial, but I 'm not providing it so you can do it yourself (you will need to be familiar with the bitwise and shift operators in order to do it).

The easy way is probably to use printf()'s %o format specifier:
scanf("%d", &n);
printf("%o", n);

Others have posted the real, production code answer, and now I see from your comments that you haven't done loops yet. Perhaps your book is trying to teach you about recursion:
void print_oct(int n)
{
if (n != 0) {
print_oct(n / 8);
printf("%d", n % 8);
}
}
This works for n > 0.

With loops you can roll up your five very similar lines like this:
for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
printf("%d", n / d % 8);
printf("\n");
d will start at 8 * 8 * 8 * 8, which is the divisor you use for n2 and then step through 8 * 8 * 8, 8 * 8, 8 and finally 1, which is the divisor for n6, printing each digit along the way.
A good compiler will actually optimize this by unrolling it back into five lines, so you'll get almost the same thing you started with. The advantage of writing it as a loop is that you can't make a mistake in just one of the lines.
The compiler will also take care of replacing divisions by 8 with shifts by 3 bits. Both give the same result in binary, but the latter is faster.

/* Converts a positive base_10 into base_b */
int DecimalToBase(int n, int b)
{
int rslt=0, digitPos=1;
while (n)
{
rslt += (n%b)*digitPos;
n /= b;
digitPos *= 10;
}
return rslt;
}

Use %o format specifier inside printf
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
printf("%o", n);

Since only basics are introduced you don't want (at least at this point) to use functions, loops, bitwise operators, %o format specifier and all that stuff. Here is my basic solution:
int n, d1, d2, d3, d4, d5, o;
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
d5 = n % 8;
n /= 8;
d4 = n % 8;
n /= 8;
d3 = n % 8;
n /= 8;
d2 = n % 8;
n /= 8;
d1 = n % 8;
o = 10000 * d1 + 1000 * d2 + 100 * d3 + 10 * d4 + d5;
printf("In octal, your number is: %.5d\n", o);
Note that since n is not needed in output, you can modify (divide) it for every step (thus saving divides, which are computationally and relatively expensive). You are safe up to 32767 (in octal: 77777), as 32768 (8*8*8*8*8 = 8^5 = (2^3)^5 = 2^15) is the first number, that requires six digits in octal: 100000.
This o variable is not really needed, morever it will not work when int is signed 16-bit (on some ancient system), so from this point it's better to just print separate digits.

Existing answers aren't clean enough for my liking. Here's mine:
#include <stdio.h>
#define OCTALBASE 8
#define OCTALSIZE 8
int main(int argc, char **argv) {
int indecimal = 1337;
char output[OCTALSIZE + 1];
output[OCTALSIZE] = '\0';
int outindex = OCTALSIZE;
int outdigit = 0;
int outvalue = indecimal;
while (--outindex >= 0) {
outdigit = outvalue % OCTALBASE;
if (outvalue > 0 || outdigit > 0)
{ output[outindex] = '0' + outdigit; }
else { output[outindex] = ' '; }
outvalue /= OCTALBASE;
}
fprintf(stdout, "{ DEC: %8d, OCT: %s }\n", indecimal, output);
fflush(stdout);
return 0;
}
Result:
{ DEC: 1337, OCT: 2471 }

Convert Decimal to Octal in C Language
#include<stdio.h>
#include<conio.h>
void main()
{
A:
long int n,n1,m=1,rem,ans=0;
clrscr();
printf("\nEnter Your Decimal No :: ");
scanf("%ld",&n);
n1=n;
while(n>0)
{
rem=n%8;
ans=(rem*m)+ans;
n=n/8;
m=m*10;
}
printf("\nYour Decimal No is :: %ld",n1);
printf("\nConvert into Octal No is :: %ld",ans);
printf("\n\nPress 0 to Continue...");
if(getch()=='0')
goto A;
printf("\n\n\n\tThank You");
getch();
}

Related

A function that takes an integer and inserts zeros between its digits

The function should take the address of the integer and modify it by inserting zeros between its digits. For example:
insert_zeros(3) //3
insert_zeros(39) //309
insert_zeros(397) //30907
insert_zeros(3976) //3090706
insert_zeros(39765) //309070605
My code:
#include <stdio.h>
#include <math.h>
void insert_zeros(int* num);
int main() {
int num;
printf("Enter a number:");
scanf("%d", num);
insert_zeros(&num);
printf("Number after inserting zeros: %d", num);
return 0;
}
void insert_zeros(int* num){
int count = 0;
int tmp = *num;
//Count the number of digits in the number
while(tmp != 0){
tmp /= 10;
count++;
}
//calculating the coefficient by which I will divide the number to get its digits one by one
int divider = (int)pow(10, count-1);
int multiplier;
tmp = *num;
*num = 0;
/*
The point at which I'm stuck
Here I tried to calculate the degree for the number 10
(my thought process and calculations are provided below)
*/
(count >= 3)? count += (count/2): count;
//the main loop of assembling the required number
while (count >= 0){
multiplier = (int)pow(10, count); //calculating a multiplier
*num += (tmp / divider) * multiplier; //assembling the required number
tmp %= divider; //removing the first digit of the number
divider /= 10; //decreasing divider
count -= 2; //decreasing the counter,
//which is also a power of the multiplier (witch is 10)
}
}
My idea consists of the following formula:
For number "3" I shold get "30" and it will be:
30 = (3 * 10^1) - the power is a counter for number "3" that equals 1.
For number "39" it will be "309":
309 = (3 * 10^2) + (9 * 10^1)
For number "397" it will be "30907":
30907 = (3 * 10^4) + (9 * 10^2) + (7 * 10^0)
For number "3976" it will be "3090706":
3090706 = (3 * 10^6) + (9 * 10^4) + (7 * 10^2) + (6 * 10^0) - with each iteration power is decreasing by 2
For number "39765" it will be "309070605":
309070605 = (3 * 10^8) + (9 * 10^6) + (7 * 10^4) + (6 * 10^2) + (5 * 10^0)
And so on...
For a 3-digit number, the start power should be 4, for a 4-digit number power should be 6, for a 5-digit it should be 8, for 6-digit it should be 10, etc.
That algorithm works until it takes a 5-digit number. It outputs a number like "30907060" with an extra "0" at the end.
And the main problem is in that piece of code (count >= 3)? count += (count/2): count;, where I tried to calculate the right power for the first iterating through the loop. It should give the right number to which will be added all the following numbers. But it only works until it gets a 5-digit number.
To be honest, so far I don't really understand how it can be realized. I would be very grateful if someone could explain how this can be done.
As noted in comments, your use of scanf is incorrect. You need to pass a pointer as the second argument.
#include <stdio.h>
#include <math.h>
int main(void) {
int num;
scanf("%d", &num);
int num2 = 0;
int power = 0;
while (num > 0) {
num2 += (num % 10) * (int)pow(10, power);
num /= 10;
power += 2;
}
printf("%d\n", num2);
return 0;
}
There's an easy recursive formula for inserting zeros: IZ(n) = 100*IZ(n/10) + n%10.
That gives a very concise solution -- here the test cases are more code than the actual function itself.
#include <stdio.h>
#include <stdint.h>
uint64_t insert_zeros(uint64_t n) {
return n ? (100 * insert_zeros(n / 10) + n % 10) : 0;
}
int main(int argc, char **argv) {
int tc[] = {1, 12, 123, 9854, 12345, 123450};
for (int i = 0; i < sizeof(tc)/sizeof(*tc); i++) {
printf("%d -> %lu\n", tc[i], insert_zeros(tc[i]));
}
}
Output:
1 -> 1
12 -> 102
123 -> 10203
9854 -> 9080504
12345 -> 102030405
123450 -> 10203040500
Adapting some code just posted for another of these silly exercises:
int main() {
int v1 = 12345; // I don't like rekeying data. Here's the 'seed' value.
printf( "Using %d as input\n", v1 );
int stack[8] = { 0 }, spCnt = -1;
// Peel off each 'digit' right-to-left, pushing onto a stack
while( v1 )
stack[ ++spCnt ] = v1%10, v1 /= 10;
if( spCnt == 0 ) // Special case for single digit seed.
v1 = stack[ spCnt ] * 10;
else
// multiply value sofar by 100, and add next digit popped from stack.
while( spCnt >= 0 )
v1 = v1 * 100 + stack[ spCnt-- ];
printf( "%d\n", v1 );
return 0;
}
There's a ceiling to how big a decimal value can be stored in an int. If you want to start to play with strings of digits, that is another matter entirely.
EDIT: If this were in Java, this would be a solution, but the problem is in C, which I'm not sure if this can convert to C.
This may be a lot easier if you first convert the integer to a string, then use a for loop to add the zeros, then afterward reconvert to an integer. Example:
int insert_zeros(int num) {
String numString = Integer.toString(num);
String newString = "";
int numStringLength = numString.length();
for (int i = 0; i < numStringLength; i++) {
newString += numString[i];
// Only add a 0 if it's not the last digit (with exception of 1st digit)
if (i < numStringLength - 1 || i == 0) newString += '0';
}
return Integer.parseInt(newString);
}
I think this should give you your desired effect. It's been a little bit since I've worked with Java (I'm currently doing JavaScript), so I hope there's no syntax errors, but the logic should all be correct.

Octal to decimal and binary with wrong outputs

We were assigned a task to convert octal numbers to binary and decimal. Smaller numbers works just fine but it then gives a different output at a higher input. Here is the code:
#include <stdio.h>
void main() {
unsigned long n, g, ans = 1, r = 0, dec = 0, place = 1, bin = 0;
printf("Conversion: Octal to decimal and binary.\n");
printf("Enter number: ");
scanf("%lu", &n);
printf("%lu is ", n);
for (g = n; g != 0; ans = ans * 8) {
r = g % 10;
dec = dec + r * ans;
g = g / 10;
}
printf("%lu in Decimal Form. \n", dec);
printf("%lu is ", n);
for (; dec != 0; place = place * 10) {
r = dec % 2;
bin = bin + (r * place);
dec = dec / 2;
}
printf("%lu in Binary Form.\n", bin);
}
We were only required to use limited data types and control structures. No arrays, strings, functions or such.
The input in our teacher's test case is 575360400 which must print an output of 101111101011110000100000000 in binary and 100000000 in decimal. But the output in binary is 14184298036271661312. I used unsigned long already and it just won't work.
I don't know how this is possible with the given restrictions and your comments and answers will be really much of a help.
Smaller numbers works just fine but it then gives a different output at a higher input.
Overflow
Input "575360400" (base 8) converts to a 27-bit value. For place = place * 10 ... bin = bin + (r * place); to work, bin needs to be a 90-bit unsigned long. unsigned long is certainly 64-bit or less.
OP needs a new approach.
I'd start with reading the octal input with scanf("%lo", &n); and printing the decimal with printf("%lu\n", n);.
To print in binary, without arrays, functions, etc., consider a mask, first with the most significant bit, that is shifted right each iteration.
bool significant_digit = false;
// Form 0b1000...0000
// 0b1111... - 0b01111..
unsigned long mask = ULONG_MAX - ULONG_MAX/2;
while (mask) {
bool bit = mask & n;
if (bit || significant_digit || mask == 1) {
significant_digit = true;
printf("%d", bit);
}
mask >>= 1;
}
printf("\n", bit);
}
Better approaches exist. Yet with OP's artificial limitations: "No arrays, strings, functions or such.", I opted for something illustrative and simple.
Or wait until 2023
C2x expected to support printf("%lb\n", n);. Just ask the professor for an extension 😉.

Reversing last n digits of an Integer in C

I need to write a program that takes 2 digits(X and n) and then prints X with last n digits of X reversed.
For example
Input: 12345 3
Output: 12543
Input: 523 2
Output: 532
I already wrote a control mechanism for checking n is greater or equal than the number of digits of X
For example if inputs are 6343 and 7, program prints that inputs should be changed and takes input again.
My main problem is I couldn't find an algorithm for reversing last n digits. I can reverse any int with this code
int X, r = 0;
printf("Enter a number to reverse\n");
scanf("%d", &n);
while (X != 0)
{
r = r * 10;
r = r + n%10;
X = X/10;
}
printf("Reverse of the number = %d", r);
But I couldn't figure how two reverse just last digits. Can you give me any idea for that?
I couldn't figure how to reverse just last digits
Separate the number using pow(10,n) - see later code.
unsigned reverse_last_digits(unsigned x, unsigned n) {
unsigned pow10 = powu(10, n);
unsigned lower = x%pow10;
unsigned upper = x - lower;
return upper + reverseu(lower, n);
}
Create a loop that extracts the least-significant-digit (%10) and builds up another integer by applying that digit. (y = y*10 + new_digit)
unsigned reverseu(unsigned x, unsigned n) {
unsigned y = 0;
while (n-- > 0) {
y = y*10 + x%10;
x /= 10;
}
return y;
}
For integer type problems, consider integer helper functions and avoid floating point functions like pow() as they may provide only an approximate results. Easy enough to code an integer pow().
unsigned powu(unsigned x, unsigned expo) {
unsigned y = 1;
while (expo > 0) {
if (expo & 1) {
y = x * y;
}
expo >>= 1;
x *= x;
}
return y;
}
Test
int main() {
printf("%u\n", reverse_last_digits(12345, 3));
printf("%u\n", reverse_last_digits(523, 2));
printf("%u\n", reverse_last_digits(42001, 3));
printf("%u\n", reverse_last_digits(1, 2));
}
Output
12543
532
42100
10
Code uses unsigned rather than int to avoid undefined behavior (UB) on int overflow.
It is an easy one.
1. let say the number you want to reverse is curr_number;
2. Now, the places you want to reverse is x;
(remember to verify that x must be less than the number of digit of curr_number);
3. now, just take a temp integer and store curr_number / pow(10,x) ('/' = divide and pow(10,x) is 10 to the power x)
4. now, take a second number temp2, which will store curr_number-(temp * pow(10,x) )
5. reverse this temp2 (using your function)
6. now, answer = (temp * pow(10,x) ) + (temp2) //(note temp2 is reversed)
example with steps:
curr_number = 1234567
places you want to reverse is 3
temp = 1234567 / (10^3) i.e (1234567/1000) = 1234 (because it is int type)
temp2 = 1234567 - (1234*10^3) i.e 1234567 - 1234000 = 567
reverse(567) = 765
answer = (1234 * 10^3) + 765 = 1234765
Create two variables
lastn which stores the last n digits (345)
r which stores the reversed last n digits (543)
Subtract lastn from the original number (12345 - 345 = 12000)
Add r to the above number (12000 + 543 = 12543)
int c = 0; // count number of digits
int original = x;
int lastn = 0;
while (x != 0 && c < n) {
r = r * 10;
r = r + x % 10;
lastn += (x % 10) * pow(10, c);
x = x / 10;
c++;
}
printf("reversed: %d\n", original - lastn + r);
In case you don't have problems using char, you can do this
#include <stdio.h>
#include <string.h>
#define SIZE 10
int main() {
char n[SIZE]; // the Number;
int x; // number of last digits of n to reverse
int len; // number of digits of n
scanf("%s%d", n, &x);
len = strlen(n);
for(int i = 0; i < len; i++) {
i < len - x ? printf("%c", n[i]) : printf("%c", n[2*len -1 - i - x]);
}
return 0;
}
If you want you can make the program more readable by splitting the for in two
for(int i = 0; i < len - x; i++) {
printf("%c", n[i]);
}
for(int i = len-1; i >= len - x; i--) {
printf("%c", n[i]);
}
Note: the program won't work if n > x (i.e. if you want to swap more digits than you got)

Project Euler+ #97 modular exponentation not working

I am trying to solve Project Euler+ #97 from Hackerrank. The problem asks to calculate the last 12 digits of A x B ** C + D. My attempt was to use the modular exponentiation mod 10 ** 12 from Wikipedia in order to efficiently calculate the last 12 digits and avoid overflow. However, for all cases aside from the sample 2 x 3 ** 4 + 5 I am getting wrong. According to the constraints there should be no overflow for unsigned long long.
The problem:
Now we want to learn how to calculate some last digits of such big numbers. Let's assume we have a lot of numbers A x B ** C + D and we want to know last 12 digits of these numbers.
Constraints:
1 ≤ T ≤ 500000
1 ≤ A, B, C, D ≤ 10 ** 9
Input: First line contains one integer T - the number of tests.
T lines follow containing 4 integers (A, B, C and D) each.
Output: Output exactly one line containing exactly 12 digits - the last 12 digits of the sum of all results. If the sum is less than 10 ** 12 print corresponding number of leading zeroes then.
My attempt in C
#include <stdio.h>
int main() {
const unsigned long long limit = 1000000000000;
int cases;
for (scanf("%d", &cases); cases; --cases) {
// mult = A, base = B, exp = C, add = D
unsigned long long mult, base, exp, add;
scanf("%llu %llu %llu %llu", &mult, &base, &exp, &add);
base = base % limit;
while (exp) {
if (exp & 1) {
mult = (mult * base) % limit;
}
exp >>= 1;
base = (base * base) % limit;
}
printf("%012llu\n", (mult + add) % limit);
}
return 0;
}
I think you can overflow unsigned long long math (e.g. - modulo 2^64) because your computation of base in your inner loop can get as high as (10^12 - 1)^2 ~= 10^24 ~= 2^79.726, which is much more than 2^64. For example, think about B = 10^6 - 1 and C = 4.
On my MacBook Pro running a 64b version of Mac OS X with clang 8.1.0:
#include <stdio.h>
int main()
{
fprintf(stdout, "sizeof(unsigned long long) = %u\n", (unsigned) sizeof(unsigned long long));
fprintf(stdout, "sizeof(__uint128_t) = %u\n", (unsigned) sizeof(__uint128_t));
fprintf(stdout, "sizeof(long double) = %u\n", (unsigned) sizeof(long double));
return 0;
}
Says:
sizeof(unsigned long long) = 8
sizeof(__uint128_t) = 16
sizeof(long double) = 16
If your platform says 16 or 10 instead for long long, then I think you are in the clear. If it says 8 like mine does, then you need to rework your answer to either force 128b (or 80b) integer math natively or mimic it some other way.
You can try __uint128_t, which is supported by gcc and clang. Otherwise, you'd need to resort to something like long double and fmodl(), which might have enough mantissa bits but might not give exact answers like you want.
Also, you don't accumulate multiple results like the task says. Here's my shot at it, based on your program, but using __uint128_t.
#include <stdio.h>
#include <stdlib.h>
#define BILLION 1000000000
#define TRILLION 1000000000000
int main()
{
const __uint128_t limit = TRILLION;
unsigned long cases = 0;
__uint128_t acc = 0;
if (scanf("%lu", &cases) != 1 || cases == 0 || cases > 500000)
abort();
while (cases-- > 0)
{
unsigned long a, b, c, d;
__uint128_t b2c = 1, bbase;
if (scanf("%lu %lu %lu %lu", &a, &b, &c, &d) != 4 ||
a == 0 || a > BILLION || b == 0 || b > BILLION ||
c == 0 || c > BILLION || d == 0 || d > BILLION)
abort();
for (bbase = b; c > 0; c >>= 1)
{
if ((c & 0x1) != 0)
b2c = (b2c * bbase) % limit; // 64b overflow: ~10^12 * ~10^12 ~= 10^24 > 2^64
bbase = (bbase * bbase) % limit; // same overflow issue as above
}
// can do modulus on acc only once at end of program instead because
// 5 * 10^5 * (10^9 * (10^12 - 1) + 10^9) = 5 * 10^26 < 2^128
acc += a * b2c + d;
}
acc %= limit;
printf("%012llu\n", (unsigned long long) acc);
return 0;
}

How do I multiply a long integer with different numbers in C program?

I am very new to C programming and I am writing a program which takes a number which is suppose to be 9 digits long. After this I multiply each digit with either 1 or 2. I am using arrays to ask user to enter their numbers. I would like to know if there is a way to multiply those 9 numbers with different numbers as one integer instead of using arrays? Here is my code with arrays:
#include <stdio.h>
int main(void) {
int sin_num[9];
int num1;
int num2, num11, num12;
int num3, num4, num5, num6, num7, num8, num9, num10;
for(num1=0; num1<9; num1++) {
printf("Enter your SIN number one by one:");
scanf("%d", &sin_num[num1]);
}
num2 = sin_num[0] * 1;
num3 = sin_num[1] * 2;
num4 = sin_num[2] * 1;
num5 = sin_num[3] * 2;
num6 = sin_num[4] * 1;
num7 = sin_num[5] * 2;
num8 = sin_num[6] * 1;
num9 = sin_num[7] * 2;
num10 = sin_num[8] * 1;
Right now I am doing this:
element 1 * 1
element 2 * 2
element 3 * 1
But how can I do, lets say if I enter 123456789 multiply with different numbers:
123456789
121212121
Well I couldn't much understand what you were asking. Anyways hope this is what you are looking for.....
#include<stdio.h>
int main()
{
long int nine_digit_num;
int step=100000000;
int digit,input_num,i;
printf("Enter 9 digit number:\n");
scanf("%ld",&nine_digit_num);
for(i=1;i<=9;i++)
{
printf("Enter a number to multiply with the %d digit:\n",i);
scanf("%d",&input_num);
digit=nine_digit_num/step; // this and the next step are used to
digit=digit%10; // obtain the individual digits.
printf("%d*%d=%d\n",digit,input_num,digit*input_num);
step=step/10;
}
return 0;
}
I'm sure there are Luhn algorithm solutions already written that you could reference, but I'm going to invent my own right now just to have a walkthrough.
Since your input is only 9 digits, it will fit in a plain 32 bit variable. I'll use unsigned on the assumption it's 32 bits or bigger, but for production code, you'd likely want to use inttypes.h uint32_t and associated scanf macros.
#include <stdio.h>
int main(void) {
unsigned sin_num, checksum, digit;
int i;
printf("Enter your SIN as a 9 digit number using only digits:\n");
if (scanf(" %9u", &sin_num) < 1) ... do error handling or just exit ...
for (i = 0; sin_num; ++i) {
digit = sin_num % 10;
sin_num /= 10;
if (i & 1) { // Double odd digits (might have this backwards; check me for your case
digit *= 2;
if (digit >= 10) digit = digit % 10 + digit / 10; // Luhn carry is strange
}
checksum += digit;
}
... do whatever else you need to do ...
It's not a single mathematical operation because Luhn's carry is too weird for magic number tricks, but it's still much more straightforward than a bunch of single digit scanf calls and array storage.

Resources