Logarithm computing without math.h - c

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.

Related

my prime number checker function not working properly

So this function is just supposed to return 0 if not prime and 1 if prime. Am I seeing something wrong? for example, when I give it 39, it says it returns 1 although 39 is not a prime.
int is_prime(int number){
if (number == 2) {
return 1;
}
else{
for(loop_counter ; loop_counter < number ; loop_counter++){
if(number%loop_counter == 0){
return 0;
}
else{
return 1;
}
}
}
}
In this loop
for(loop_counter ; loop_counter < number ; loop_counter++){
there is used an undeclared variable loop_counter. If it is a global variable then it shall not be used in the function because at least it is unclear what is its value.
Also within the loop you are interrupting its iterations as soon as number%loop_counter != 0. But this does not mean that the number is prime.
And if the user will pass a negative number or zero then the function will have undefined behavior.
The function can be defined the following way
int is_prime( unsigned int n )
{
int prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
The function at first excludes all even numbers except 2 because even numbers are not prime numbers. And it also excludes the number 1 because the number 1 is not prime by the definition.
int prime = n % 2 == 0 ? n == 2 : n != 1;
So within the loop there is no sense to consider divisors that are even.
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
^^^^^^
Then within the loop there is a check whether the given odd number n is divisible by an odd divisor
prime = n % i != 0;
If n % i is equal to 0 then the variable prime gets the value 0 and the loop stops its iterations due to the condition in the loop.
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
^^^^^
that can be rewritten also like
for ( unsigned int i = 3; prime != 0 && i <= n / i; i += 2 )
^^^^^^^^^^
regarding:
for(loop_counter ; loop_counter < number ; loop_counter++){
the variable: loop_counter is not initialized (nor even declared)
Perhaps you meant:
for( int loop_counter = 0; loop_counter < number ; loop_counter++){
The following proposed code:
cleanly compiles
performs the desired functionality
is NOT the fastest/best way to check if a number is prime. Rather it is a brute force method
The OPs posted code has several problems as discussed in comments to the OPs question, so will not be repeated here.
Now, the proposed code:
int is_prime(int number)
{
for( int loop_counter = 2 ; loop_counter < number ; loop_counter++)
{
if(number%loop_counter == 0)
{
return 0;
}
}
return 1;
}

Understanding calling one function inside another C

I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}

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.

Value is 20,10000, error appeared

To test two 32-bit integers, m whose factorial is m! can be divisible by n. If it can, the function divides() returns 1, otherwise 0.
As the codes below, the problem is when m = 2010000, error happened. Could you please explain why?
#include <stdio.h>
long factorial(long n){
if((n == 0) || (n == 1)) return 1;
else{
return (n * factorial(n-1));
}
}
int divides (long n,long m)
{
long facN;
printf("n=%ld ",n);
facN = factorial(n);
if(m != 0){
if(facN == 1) return 0;
else{
if(facN % m == 0) return 1;
else if((facN % m) != 0)return 0;
}
}
else if(m == 0) return 0;
}
int main()
{
printf("%d", divides(2000000,1));
}
You need to compute the factorial with the modulus already taken into account. Using the following identity:
(a * b) % n = ((a % n) * (b % n)) % n
we can compute the factorial as:
m! % n = (((((1 % n) * 2) % n) * 3) % n) ...) % n
A 32-bit integer can only store factorials from 0 to 12.
1*2*3*4*5*6*7*8*9*10*11*12
479001600
1*2*3*4*5*6*7*8*9*10*11*12*13
6227020800
Given that 69! is of the order of 10^98 you are probably looking at value overflows but you might also be looking at running out of memory/stack as you will be nesting 2 million deep in your recursion.
Also your check if((facN % m) != 0) is redundant as it is called in the else to if(facN % m == 0)
If your cause is all about finding out whether if m! for an m is divisible by an n, do not calculate the factorial at all.
Rather split n to its factors, check if there are enough many of those inside the numbers ranging from 1 to m, inclusive.
For example; for m = 7 and n = 28, the process should be like the following:
n % 2 == 0 ? yes
n /= 2
2 * 1 <= m ? yes
n % 2 == 0 still? yes
n /= 2
2 * 2 <= m ? yes
n % 2 == 0 still? no
n % 3 == 0 ? no
...
n % 7 == 0 ? yes
n /= 7
7 <= m ? yes
n reached 1, return 1
Something like this. If you cannot manage to write this, then you probably shouldn't be dealing with that question yet. Still, if you want, leave a comment, I can edit my answer to include a working code.
I am adding a working example, using the logic above to display whether n is a divisor of m!, just to assure you that this thing does indeed work:
#include <stdio.h>
// this function basically compares the powers of the
// prime divisors of factee and divisor
// ... returns 1 if the powers in divisor are
// ... less than or equal to the powers in factee
// ... returns 0 otherwise
int divides( long factee, long divisor ){
int amount;
for ( int i = 2; i <= factee; i++ ){
if ( divisor % i )
continue;
amount = 0;
int copy = factee;
while ( copy ){
copy /= i;
amount += copy;
}
while ( divisor % i == 0 ){
if ( !amount )
return 0;
amount--;
divisor /= i;
}
if ( divisor == 1 )
return 1;
}
return 0;
}
int main( )
{
printf( "%d", divides( 20, 10000 ) );
getchar( );
return 0;
}
amount variable calculates the amount of i there are inside the m!. In the while loop in which it gets calculated, with the first cycle, the amount of is are added, then with the second cycle, the amount of i * is are added, and so on, until there aren't any.
For example, with m = 5 and i = 2, m / 2 is 2, which is the amount of occurrence of the factor 2 inside the 5!. Then m / 2 / 2, which is 1, is the amount of occurrence of the factor 2 * 2 == 4 inside the 5!. Then m / 2 / 2 == 0 is the count for 2 * 2 * 2 == 8, which causes the loop to end due to the 0 encounter.
Edit
I fixed something important in the code, removed the outermost while which was there for nothing, something I had put as I started and apparently forgot to remove, causing potential infinite-loops. Here I also made an improved version of the function that generally runs faster than the one above:
#include <stdio.h>
// this function basically compares the powers of the
// prime divisors of factee and divisor
// ... returns 1 if the powers in divisor are
// ... less than or equal to the powers in factee
// ... returns 0 otherwise
int divides( long factee, long divisor ){
int amount;
if ( divisor % 2 == 0 ){
amount = 0;
int copy = factee;
while ( divisor % 2 == 0 ){
if ( !amount ){
copy /= 2;
if ( !copy )
return 0;
amount += copy;
}
amount--;
divisor /= 2;
}
if ( divisor == 1 )
return 1;
}
for ( int i = 3; i <= factee; i += 2 ){
if ( divisor % i )
continue;
amount = 0;
int copy = factee;
while ( divisor % i == 0 ){
if ( !amount ){
copy /= i;
if ( !copy )
return 0;
amount += copy;
}
amount--;
divisor /= i;
}
if ( divisor == 1 )
return 1;
}
return 0;
}
int main( ) {
printf( "%d", divides( 34534564, 345673455 ) );
//printf( "%d", divides( 20, 10000 ) );
getchar( );
return 0;
}
long can support a value in the range of -2,147,483,647 to 2,147,483,647, here 2000000! is out of the range of long, that is why it is showing error.

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)
}

Resources