write C program to compute the numeric root - c

The numeric root of x is computed as follows:
a) Compute the sum, y, of all of x’s (decimal) digits;
b) If y is greater than 10, then set x to y and go to step a). Otherwise, y is x’s numerical root.
Thus, the numeric root of 10, 202 and 875 are 1, 4 and 2, respectively.
Here is my code:
#include <stdio.h>
int main(void)
{
int x, y, index, found;
found = 0;
scanf("%d", &x);
if (x < 0)
{
printf("The input number must be nonnegative.\n");
}
else
{
y = 0;
index = x % 10;
while (found != 1)
{
while (x > 10)
{
y = y + index;
x = (x - index) / 10;
index = x % 10;
}
y = y + index;
if (y < 10)
{
printf("%d\n", y);
found = 1;
}
else
{
x = y;
}
}
}
return 0;
}
My output are always numbers like "-2147483623" etc.
Any help will be appreciated.

Your solution can be greatly simplified with the use of a simple function.
See the following solution using the Ada language:
with Ada.Integer_Text_IO; use Ada.Integer_Text_Io;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
Inpt_Value : Natural;
Root : Natural := 0;
function Find_Root(X : Natural) return Natural is
Value : Natural := X;
Root : Natural := 0;
begin
while Value > 0 loop
Root := Root + (Value mod 10);
Value := Value / 10;
end loop;
return Root;
end Find_Root;
begin
Put("Enter a non-negative integer: ");
Get(Item => Inpt_Value);
Root := Find_Root(Inpt_Value);
while Root > 10 loop
Root := Find_Root(Root);
end loop;
Put_Line(Root'Image);
end Main;

I think that your problem is here :
if(y < 10){
printf("%d\n",y);
found = 1;
}
else{
x = y;
}
in your else statement you assign the value of x to y, but you don't change the value of y.
Maybe you should do something like this :
if(y < 10){
printf("%d\n",y);
found = 1;
}
else{
x = y;
y = 0;
index = x % 10;
}
In your entire program you don't seem to decrease or reset the value of y, that's why once the else block entered, there is no way to enter the if block, because y will increase and always be greater than 10 until an overflow happens, that's why y is negative at the end.
PS: Always use a debugger or printf statements it will help you detect such problems.

Related

C - getting prime numbers using this algorithm

I am fighting some simple question.
I want to get prime numbers
I will use this algorithm
and... I finished code writing like this.
int k = 0, x = 1, n, prim, lim = 1;
int p[100000];
int xCount=0, limCount=0, kCount=0;
p[0] = 2;
scanf("%d", &n);
start = clock();
do
{
x += 2; xCount++;
if (sqrt(p[lim]) <= x)
{
lim++; limCount++;
}
k = 2; prim = true;
while (prim && k<lim)
{
if (x % p[k] == 0)
prim = false;
k++; kCount++;
}
if (prim == true)
{
p[lim] = x;
printf("prime number : %d\n", p[lim]);
}
} while (k<n);
I want to check how much repeat this code (x+=2; lim++; k++;)
so I used xCount, limCount, kCount variables.
when input(n) is 10, the results are x : 14, lim : 9, k : 43. wrong answer.
answer is (14,3,13).
Did I write code not well?
tell me correct point plz...
If you want to adapt an algorithm to your needs, it's always a good idea to implement it verbatim first, especially if you have pseudocode that is detailed enough to allow for such a verbatim translation into C-code (even more so with Fortran but I digress)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main (void){
// type index 1..n
int index;
// var
// x: integer
int x;
//i, k, lim: integer
int i, k, lim;
// prim: boolean
bool prim;
// p: array[index] of integer {p[i] = i'th prime number}
/*
We cannot do that directly, we need to know the value of "index" first
*/
int res;
res = scanf("%d", &index);
if(res != 1 || index < 1){
fprintf(stderr,"Only integral values >= 1, please. Thank you.\n");
return EXIT_FAILURE;
}
/*
The array from the pseudocode is a one-based array, take care
*/
int p[index + 1];
// initialize the whole array with distinguishable values in case of debugging
for(i = 0;i<index;i++){
p[i] = -i;
}
/*
Your variables
*/
int lim_count = 0, k_count = 0;
// begin
// p[1] = 2
p[1] = 2;
// write(2)
puts("2");
// x = 1
x = 1;
// lim = 1
lim = 1;
// for i:=2 to n do
for(i = 2;i < index; i++){
// repeat (until prim)
do {
// x = x + 2
x += 2;
// if(sqr(p[lim]) <= x) then
if(p[lim] * p[lim] <= x){
// lim = lim +1
lim++;
lim_count++;
}
// k = 2
k = 2;
// prim = true
prim = true;
// while (prim and (k < lim)) do
while (prim && (k < lim)){
// prim = "x is not divisible by p[k]"
if((x % p[k]) == 0){
prim = false;
}
// k = k + 1
k++;
k_count++;
}
// (repeat) until prim
} while(!prim);
// p[i] := x
p[i] = x;
// write(x)
printf("%d\n",x);
}
// end
printf("x = %d, lim_count = %d, k_count = %d \n",x,lim_count,k_count);
for(i = 0;i<index;i++){
printf("%d, ",p[i]);
}
putchar('\n');
return EXIT_SUCCESS;
}
It will print an index - 1 number of primes starting at 2.
You can easily change it now--for example: print only the primes up to index instead of index - 1 primes.
In your case the numbers for all six primes up to 13 gives
x = 13, lim_count = 2, k_count = 3
which is distinctly different from the result you want.
Your translation looks very sloppy.
for i:= 2 to n do begin
must translate to:
for (i=2; i<=n; i++)
repeat
....
until prim
must translate to:
do {
...
} while (!prim);
The while prim... loop is inside the repeat...until prim loop.
I leave it to you to apply this to your code and to check that all constructs have been properly translated. it doesn't look too difficult to do that correctly.
Note: it looks like the algorithm uses 1-based arrays whereas C uses 0-based arrays.

Calculate the number of all possible execution paths in a C function

I am desperately looking for a way to easily calculate the number of all possible execution paths in a C function.
For example, for the following function I would expect to get a result of 3 (if there is a chance based on the values that 'i' gets to enter any of the 'if' statements)
void test(void)
{
if (i>0)
x = x + 1;
else if (i>10)
x = x + 2;
else
x = x + 3;
}
Use comma operator as
int test(void)
{
int ways = 0;
if (++ways, i>0)
x = x + 1;
else if (++ways, i>10)
x = x + 2;
else
{
x = x + 3;
++ways;
}
return ways;
}

Logarithm computing without math.h

I'm trying to compute ln(x) by Taylor series. Here is my code:
#define N 10
float ln(float x){
int i;
float result;
float xt;
float xtpow;
int sign;
if(x > 0 && x <= 1){
xt = x - 1.0;
sign = -1;
xtpow = 1.0;
result = 0;
for(i = 1 ; i < N + 1; i++ );
{
// Problem here
printf("%d\n", i);
sign = sign * (-1);
xtpow *= xt;
result += xtpow * sign / i;
}
}else if(x >= 1)
{
return -1 * ln(1.0 / x);
}
return result;
}
The problem is with my series cycle(see above). It seems like after 1 cycle variable i becomes equal N + 1, and nothing going on after it. Have you any ideas why it is so?
It seems like after 1 cycle variable i becomes equal N + 1
remove ; after for loop:
for(i = 1 ; i < N + 1; i++ );
^
Your loop continue execute without executing code in block you putted in braces { } after for loop and for loop just increments i till for loop breaks. After the loop code block (where you commented "problem is here") get executes with i = N + 1 value.
I am not sure but I have an additional doubt about conditional expressions in if(). You code pattern is something like:
if(x > 0 && x <= 1){ <-- "True for x == 1"
// loop code
}
else if(x >= 1){ <-- "True for x == 1"
// expression code here
}
So for x == 1 else code never execute. Check this code too.

Control Instructions in C

I am not understanding for loop statement and expression following it. Please do help me understand.
#include<stdio.h>
int main()
{
int x = 1;
int y = 1;
for( ; y ; printf("%d %d\n",x,y))
y = x++ <= 5;
return 0;
}
And the output I got
2 1
3 1
4 1
5 1
6 1
7 0
y = x++ <= 5; ==> y = (x++ <= 5); ==> first compare x with 5 to check whether x is small then or equals to 5 or not. Result of (x++ <= 5) is either 1, 0 assigned to y,
As x becomes > 5, (x++ <= 5) becomes 0 so y = 0 and condition false and loop break,
Basically the for syntax is:
for(StartCondition; Test; PostLoopOperation) DoWhileTestPasses;
In this case:
StartCondition == None
Test == (y != 0)
PostLoopOperation == do some printing
DoWhileTestPasses == set y to zero if x > 5 otherwise to non-zero THEN increment x.
Which is all rather bad practice because it is confusing.
Would be better written as:
int x=0;
int y=0;
for(y=0; y = (x <= 6); x++)
{
printff("%d %d\n",x,y);
}
return(0);
In y = x++ <= 5;, y stores the value that is output by the condition x++ <= 5 (here x++ is post increment). If the condition is true then y = 1 else y = 0.
for( ; y ; printf("%d %d\n",x,y))
In the for loop you are printing the values of x and y after executing the for loop body.
Initialize your variables:
int x = 1; int y = 1;
There are 3 statements for the for loop: -1. Initialize, 2. Condition, 3. Iteration:increment/decrement
In your case, you did not provide the initialize condition, however, you have the part of condition and incrementation. I do not think your for loop is used in the correct way.
You should swap the part of incrementation with your body like this:
for(; y; y = x++ <= 5;)
printf("%d %d\n", x, y)
First, you check whether the condition is true or not, y is true or not. Then, you print x and y out. Then, the part of incrementation is executed, x++ <= 5 or not. The result is assigned to y. It does so until your condition is false, y == false.
NOTE: For the good programming, you should enclose your body with a curly braces.
similar to this
int x = 1;
for( int y = 1; y!=0 ; )
{
if (x++ <= 5)
{
y = 1;
}
else
{
y = 0;
}
printf("%d %d\n",x,y);
}
Perhaps this slightly transformed (but functionally equal) code will help:
int x = 1;
int y = 1;
while (y) {
y = (x <= 5);
x = x + 1;
printf("%d %d\n", x, y)
}

Square root in C using Newton-Raphson method

In the following code, I want to replace the termination condition to: if the ratio of guess square and x is close to 1, while loop should terminate. I tried various expressions, but none run the code properly. any suggestion?
# include<stdio.h>
float absolute(float x)
{
if (x < 0)
x = -x;
return x;
}
float square(float x)
{
float guess = 1;
while(absolute(guess*guess - x) >= 0.0001 )
guess = ((x/guess) + guess) / 2;
return guess;
}
int main(void)
{
printf("square root of 2 is %f\n", square(2));
printf("square root of 3 is %f\n", square(3));
return 0;
}
hit the answer: while statement should be like this:
while ( absoluteValue((guess * guess) / x - 1.0) >= 0.0001 )
# include<stdio.h>
double sq_root(double x)
{
double rt = 1, ort = 0;
while(ort!=rt)
{
ort = rt;
rt = ((x/rt) + rt) / 2;
}
return rt;
}
int main(void)
{
int i;
for(i = 2; i<1001; i++) printf("square root of %d is %f\n",i, sq_root(i));
return 0;
}
if the ratio of guess square and x is close to 1
Then why are you subtracting? Use ratio operator:
while(absolute( (guess*guess) / x - 1) >= 0.0001 )
It's possible you can't reach that guess*guess will be enough close to x; imagine e.g. sqrt of 2e38 - every approximation will be no closer than ~1e31 and your exit condition won't ever succeed.
The variant good for all cases is that stopping for this method occur when guess stops to change. So you would write something like
prev_guess = 0; // any initial value is ok
while (guess != prev_guess) {
...
prev_guess = guess;
}
at least it shall work for any IEEE754-compatible implementation not reaching overflow or underflow.
Also you can compare guess and prev_guess for difference (as soon as the goal is usually to match enough accuracy of root, not the value squared back).

Resources