Unexpected result of trace table - c

I am a newborn programmer and i've been studying trace tables thus far. However, it seems i'm unable to understand this one. By what i could gather the function would return (-15) as the variable 'a' receives 25 and later the 'num', which is 10, is subtracted by the former.
Yet it seems i'm wrong by PythonTutor's calculations and i still cannot get why num is still 10 after all that C magic. Would someone be so kind to explain why is this happening?
#include <stdio.h>
int num;
int func(int a, int b);
int main() {
int first = 0, sec = 50, num2;
num = 10;
num += func(first, sec);
printf("\nnum = %d\tfirst = %d\tsec = %d", num, first, sec);
return 0;
}
int func(int a, int b) {
a = (a + b) / 2;
num -= a;
return a;
}

Would someone be so kind to explain why is this happening?
Let us take this step by step
int num;
int func(int a, int b);
int main() {
// 1) `num == 0` as it is a global variable without explicit initialization.
int first = 0, sec = 50, num2;
// 2) `num` is 10
num = 10;
// 3) Before the function call, `num` is 10
num += func(first, sec);
// 7) At the end of the function call, `num` is -15 and
// the return value of 25 is added to it due to +=.
// 8) `num` is now 10 again.
printf("\nnum = %d\tfirst = %d\tsec = %d", num, first, sec);
return 0;
}
int func(int a, int b) {
a = (a + b) / 2;
// 4) `a` is 25, `num` is 10
// 5) `num` becomes 10 - 25 --> -15
num -= a;
// 6) `a == 25` and 25 is returned
return a;
}

Related

My function works good on debug, but not im main

I have to make a func that do somtheing like this 123 -> 321 with recursion
When i see work of my func via debugger i see that a changed, but when i call function on main, nothing changed
This is my code
#include <stdio.h>
#include <math.h>
long int SwapNum(long int , int);
int CountRoz(long int);
int main(){
long int a = 123;
printf("%ld", a);
SwapNum(a, CountRoz(a));
printf("%ld", a);
}
int CountRoz(long int a) {
if (a / 10 == 0)
return 1;
return 1 + CountRoz(a / 10);
}
long int SwapNum(long int a, int b) {
a +=a % 10 * pow(10, 2 * b - 1);
if (b == 1) {
return 1;
}
b--;
return SwapNum(a / 10, b);
}
Can you help me, because I cant find error
You can also try passing by reference although I'm not sure your algorithm is exactly right.
long int SwapNum(long int *, int);
...
SwapNum(&a, CountRoz(a));
...
long int SwapNum(long int *a, int b) {
*a += *a % 10 * pow(10, 2 * b - 1);
if (b == 1) { return 1; }
b--;
long int a2 = *a/10;
return SwapNum(&a2, b);
}
So, the modulus operator is probably what you're trying for in your first line in Swapnum. 123 % 10 yields the remainder of 123 divided by 10.
And remember, integer math will yield integers; 12/10 yields 1.
Let's say we start with:
123, 0
123/10, 0*10 + 123%10 => 12, 3
12/10, 3*10 + 12%10 => 1, 32
1/10, 32*10 + 1%10 => 0, 321
0, 321 => no more digits left from a, so 321 is our answer
We traverse digits in A like you planned by dividing by 10 and
also build up the return value by multiplying by 10 (plus remainder)
long int SwapNum(long int, long int);
int main(){
long int a = 12388569;
printf("%ld", a);
printf("%ld", SwapNum(a,0));
}
long int SwapNum(long int a, long int b) {
if (a == 0) return b;
return SwapNum(a/10, b*10 + a%10);
}
Hope this helps!Ron.

Must print a numerical sequence 15, 12, 24, 21, 42, 39, 78, 75, 150, 147

As I see it the numerical sequence consists of 2 separate sequences. This is the code that I have so far. I am not sure if you must use a while or a for loop. I am fairly new at coding so if someone please could help me.
if the entered value is 10 it must give the first 10 terms of the sequence, and if I enter 5 it must give me the first 5 terms of the sequence.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int a, n = 1, t, y = 1; // First Numerical Sequence
int b, m = 2, s, x = 2; // Second Numerical Sequence
int d, r, z; // Extra
printf("Enter A Tn : ");
scanf(" %d", &z);
printf("\n");
while (n <= z) {
a = 15;
r = pow(2, n - y);
d = (9 * (r - 1)) / (2 - 1);
t = a + d;
printf("%d\n", t);
n += 2;
y++;
}
while (m <= z) {
b = 12;
r = pow(2, m - x);
d = (9 * (r - 1)) / (2 - 1);
s = b + d;
printf("%d\n", s);
m += 2;
x++;
}
printf("\n");
return 0;
}
This will get the job done.
#include <stdio.h>
int main(){
int val,ic; //iteration count, will print ic*2 number
scanf("%d %d",&val,&ic);
for(int i = 0;i<ic;i++){
printf("%d ",val);
val-=3;
printf("%d ",val);
val*=2;
}
printf("\n");
}
How to compile & run:
C:\Users\stike\Desktop>rem assume you saved it in a.c
C:\Users\stike\Desktop>gcc -o a a.c
C:\Users\stike\Desktop>a
15
5
15 12 24 21 42 39 78 75 150 147
If you want to print the same sequence starting from 15 and o till a certain number which the user inputs, you can follow the following code.
Hope you understood the sequence pattern when a number is given it is printed and reduce the number by 3, then it is printed and then twice the number and printed, and again reduce by 3, likewise, it flows on.
#include <stdio.h>
int main() {
int endNum;
int beginNum = 15;
printf("Enter the end: ");//(lineA) here we initialize the variables with beginNum as 15
scanf("%d", &endNum); //(Line B) let the user to input endNum of the sequence,in the example it is 147
while ((beginNum-3) <= endNum) { // checks the condition
printf("%d ", beginNum);
if(beginNum==endNum) return 0; //check whether you print the end number.
beginNum -= 3; // reduce by 3
printf("%d ", beginNum);
beginNum *= 2; // multiply by 2
}
return 0;
}
if you don't need to user input a endNum just initialize the value 147 to variable endNum.
And delete the lines A and B.
Here's another approach using static variables
#include <stdio.h>
int next(void) {
static int last, n = 0;
if (n++ == 0) return last = 15; // 1st element of sequence
if (n % 2) return last = last * 2; // odd elements
return last = last - 3; // even elements
}
int main(void) {
for (int k = 0; k < 10; k++) {
printf("%d ", next());
}
puts("");
return 0;
}

My recursive greatest common denominator function isn't working properly

I'm trying to create a GCD (greatest common denominator) function using recursion.
I cannot understand why it isn't working properly.
For input 10 and 50 is returning 36.
Here's my code:
int main()
{
printf("Rez=%d ", gcd(10,50));
return 0;
}
int gcd(int a, int b)
{
static int n=0;
int result=1;
n++;
if(a<=1 || b<=1)
return 1;
else
{
if(a%n==0 && b%n==0)
result=n* gcd(a/n,b/n);
else
gcd(a,b);
}
return result;
}
Using a static variable is a problem because you use it in the form n * gcd(...) and the value of n shouldn't be the same than that used by the recursion. So you should pass a parameter instead. You should also add a condition to stop when n becomes greater than the smaller term :
#include <stdio.h>
int main()
{
printf("%d\n", gcd(10, 50, 1)); //==>10
printf("%d\n", gcd(7, 35, 1)); //==>7
printf("%d\n", gcd(8, 22, 1)); //==>2
printf("%d\n", gcd(49, 5, 1)); //==>1
printf("%d\n", gcd(0, 0, 1)); //==>1
printf("%d\n", gcd(4, 2, 0)); //==>0
return 0;
}
int gcd(int a, int b, int n)
{
if (n <= 0) return 0;
if (n > (a < b ? a : b) || a<=1 || b<=1) return 1;
else if(a%n==0 && b%n==0) return n * gcd(a/n, b/n, n+1);
else return gcd(a, b, n+1);
}
the static variable is the cause for the error. In
result=n* gcd(a/n,b/n);
n is evaluated after the recursion is called. So, as your recursion stops when you call gcd( 5/5, 25/5 ) and n is incremented to 6 by that call you just have
6 * gcd( 10/1, 50/1 ) = 6 * 6 * gcd( 10/2, 50/2 ) = 6 * 6 * 6 = gcd( 5/5, 25/5 ) = 6 * 6 * 6 * 1 = 216

Reverse the output of printf function in while loop

I wrote a code for a b-adic representation of a chosen number.
#include <stdio.h>
int b_adisch (int a, int b)
{
int x, y, mod, mod1;
x = a / b;
mod1 = a % b;
printf("%i\n", mod1);
do {
y = x / b;
mod = x % b;
x = y;
printf("%i\n", mod);
} while(x != 0);
return a ;
}
int main (void)
{
int a, b;
printf("pls input a ");
scanf("%i", &a);
printf("pls input b ");
scanf("%i", &b);
b_adisch(a, b);
return 0;
}
The output order will be reversed
since the printf has to be put into the while loop and the calculation starts with the last number of the representation.
Example if a = 10 and b = 2
The output is 0101
but it should be 1010
How can I change my code to make this happen?
How can i change my code to make this happen?
2 approaches:
Compute the digits from least to most significant and save in a adequate sized buffer. This is similar to OP's approach yet saves the results of each digit's computation for later printing.
#include <assert.h>
#include <limits.h>
void b_adisch(int value, int base) {
// Let us work with simple cases first.
assert(value >= 0);
assert(base >= 2 && base <= 10);
// Adequate sized buffer
char buffer[sizeof value * CHAR_BIT + 1];
// Start at end
char *end = &buffer[sizeof buffer - 1];
*end = '\0';
do {
end--;
int digit = value%base; // Find least digit
value /= base;
*end = digit + '0'; // save the digit as text
} while (value);
printf("<%s>\n", end); // print it as a string
}
Use recursion. A more radical change; This computes and prints the output of the more significant digits first.
void b_adischR_helper(int value, int base) {
// If the value is at least 2 digits, print the most significant digits first
if (value >= base) {
b_adischR_helper(value/base, base);
}
putchar(value % base + '0'); // Print 1 digit as text
}
void b_adischR(int value, int base) {
// Let us work with simple cases first.
assert(value >= 0);
assert(base >= 2 && base <= 10);
printf("<");
b_adischR_helper(value, base);
printf(">\n");
}
Test
int main() {
b_adisch(10, 2);
b_adischR(10, 2);
b_adisch(INT_MAX, 10);
b_adischR(INT_MAX, 10);
b_adisch(INT_MAX, 2);
b_adischR(INT_MAX, 2);
}
Output
<1010>
<1010>
<2147483647>
<2147483647>
<1111111111111111111111111111111>
<1111111111111111111111111111111>
You can store the output in an array as here it is stored in "arr" and later print the output in reverse order (from end to start).
#include <stdio.h>
int arr[10000]={0};
void b_adisch (int a, int b)
{
int x, y, mod, mod1,i=0,j;
x = a / b;
mod1 = a % b;
arr[i++]=mod1;
do {
y = x / b;
mod = x % b;
x = y;
arr[i++]=mod;
} while(x != 0);
for(j=i-1;j>=0;j--)
printf("%i\n",arr[j]);
}
int main (void)
{
int a, b;
printf("pls input a ");
scanf("%i", &a);
printf("pls input b ");
scanf("%i", &b);
b_adisch(a, b);
return 0;
}

Removing numbers 8 and 9 from a variable. What am I doing wrong?

I'm trying to input two numbers and remove 8s and 9s (not convert them, only remove unneeded numbers) so they can fit in the octal base.
When I run the program and input the numbers, they are almost correctly returned, but they are deducted by a bit.
I still don't know why and how to fix it. It might be something with zeroes, but I don't know.
int octal(int a)
{
int b = 0;
int i = 0;
while(a > 0){
if((a % 10) <= 7){
b= pow(10,i) * (a%10)+b;
i++;
}
a=a/10;
}
return b;
}
int main()
{
int j, o, a, b;
scanf(" %d %d", &j, &o);
a=octal(j);
b=octal(o);
printf("%d\n%d\n",a,b);
return 0;
}
edit: Example
Input: 72349 and 91238
Output: 7233 and 122
Code is encountering a weak double pow() that is returning values near the expected mathematical result. When the result is just under a whole number, the conversion back to int results in fraction truncation - results appear 1 less then expected.
Could use round(pow(10,i)) or better yet, stay with int math as follows.
Other simplifications possible, but minimal code changes to outline OP's issue.
int octal(int a) {
int b = 0;
int i = 0;
int pow10 = 1;
while (a > 0) {
if ((a % 10) <= 7) {
//b = pow(10,i) * (a%10)+b;
b = pow10 * (a % 10) + b;
pow10 *= 10;
i++;
}
a = a / 10;
}
return b;
}
Care for a walk on the recursive side of life?
int octal(int a) {
assert(a >= 0);
while (a >= 8) {
int digit = a%10;
a /= 10;
if (digit < 8) {
return octal(a)*10 + digit;
}
}
return a;
}

Resources