Primality Test Comparison [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I found a new primality test below which determines if 1000000007 is prime.
How does its speed compare to other existing primality algorithms?
Does it win the award for most "computationally worthless" primality test?
Thanks.
EDIT
Was able to improve speed using this method described here:
https://math.stackexchange.com/questions/3979118/speedup-primality-test
"So it's enough to go from x=n/2 up to n/2+√n/2. With this improvement, your algorithm will still be somewhat slower than your isPrimeNumber routine--just because calculating a gcd is slower than calculating divisibility. This will be feasible for testing numbers with maybe 15-20 digits, but you would need completely different methods to test something much larger, like the 183-digit number you mention."
// Primality Test
// Every n is prime if all lattice points on x+y=n are visible from the origin.
#include <stdio.h>
#include <stdint.h>
#include <math.h>
uint64_t gcd(uint64_t a, uint64_t b)
{
return (b != 0) ? gcd(b, a % b) : a;
}
int isPrimeNumber(uint64_t n)
{
if (n == 1) return 0;
if (n == 2 || n == 3) return 1;
if (n % 2 == 0) return 0;
// Start near line x=y.
uint64_t x = (n / 2) + 2;
uint64_t y = n - x;
uint64_t count = sqrt(n) / 2;
for (uint64_t i = 0; i < count; ++i) {
// Check lattice point visibility...
if (gcd(x, y) != 1) return 0;
x++; y--;
}
return 1;
}
int main(int argc, char* argv)
{
uint64_t n = 1000000007;
if (isPrimeNumber(n) == 1)
{
printf("%llu prime.", n);
}
else
{
printf("%llu not prime.", n);
}
return 0;
}

When you write any code, you should do basic debugging to verify that your code does what you think it does. Run your code on a few small numbers; print values of x and y to verify that it does the correct checks.
In addition to this, if you mix integers and floating-point variables, you should be careful: implicit conversions e.g. from float to unsigned can lead to data loss and completely incorrect calculations. Compilers usually warn about this; you should compile with all warnings enabled -Wall and pay attention to what the compiler says.
It looks like you should always have x + y = n during your computations - this is your invariant. This can be more easily expressed like this:
// initialization
x = n / 2;
y = n - x;
// it should be evident that your invariant holds here
do {
...
x++; y--;
// your invariant holds here too, by induction
}

Related

Sum of odd numbers using recursion [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
This might be simple but I'm new to recursion in c. I want to find the sum of odd integers based on user's input. For example if user inputs 3, function returns 9 (1 + 3 + 5 = 9)
int recursiveSumNOdd(int n)
{
int start = -2; //later start = start+2, so it starts at 0
int n1 = n*2; //total number of digits with rec
int num = 0;
int sum=0;
int count=0;
if(start>=n1)
{
return 0;
}
else
{
start = start+2;
count++;
sum = sum +recursiveSumNOdd(start);
}
return sum;
}
Explanations in comment:
int recursiveSumNOdd(int n) {
if (n == 1 || n == 0)// first "if" in a recursive is its stop condition
return n;
return 2 * n - 1 + recursiveSumNOdd(n-1); // formula for 2->3, 3->5 etc
}
int main(void) {
printf("%d\n", recursiveSumNOdd(3));
return 0;
}
NB: You may want to handle integer overflow
NB2: You can have a mathematics formula to return instantly the result, it is way better, but I guess it was to understand better recursion?
return n * n; // the sum of odd numbers is the square of user's input
You are over-complicating things.
You cannot have the sum of negative elements.
int sum_n_odd(unsigned n)
{
What is the sum of 0 (zero) elements?
if (n == 0) return 0;
If you knew the sum of n - 1 numbers, what is the sum of n numbers?
return sum_n_odd(n - 1) + something; // something is easy to figure out
}

Decomposition into prime factors [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
So I am running into an issue that I can't seem to fix. I want to display the factor and the power that it is raised to(basically prime factor decomposition), I had done this in python but for some reason I can't implement this in C and this is what I came up with
#include<stdio.h>
#include<math.h>
int main()
{
int i = 2, p, c, n;
scanf("%d", n);
while (n > 9)
{
p = 0;
c = 1;
while (n % i == 0)
{
for (int d = 2; d <= i / 2 + 1; d++)
if (i % d == 0 && i % 2 != 0)
c = 0;
if (c == 1)
{
p = p + 1;
n = n / i;
}
if (p != 0)
{
printf("%d %d", i, p);
printf("\n");
}
i = i + 1;
}
}
return 0;
}
Problem #1 (although it's not your main problem) is that you're missing a pointer in your scanf call:
scanf("%d", n);
That needs to be
scanf("%d", &n);
(My compiler warned me about this right away. Not sure why yours didn't.)
Problem #2 is that while (n > 9) is just totally wrong. I think you want while (n > 1).
Problem #3 is that the i = i + 1 step is misplaced. You need to do that whether or not i was a factor, so it needs to be at the end of the outermost loop.
And then problem #4 is the code that starts with
for (int d = 2; d <= i / 2 + 1; d++)
It looks like you're trying to check whether i is prime, although you're doing it too late: you're already inside the if where you test whether i is a factor of n. Also you don't have a proper loop to count how many times i is a factor of n.
It turns out, though, that you don't actually need to test whether i is prime, so let's leave the primality-testing step out for a moment and see what happens.
Here's the first fixed version:
#include <stdio.h>
int main()
{
int i = 2, p, n;
scanf("%d", &n);
while (n > 1)
{
if (n % i == 0) /* if i is a factor */
{
p = 0;
while (n % i == 0) /* count how many times i is a factor */
{
n /= i;
p++;
}
printf("%d %d\n", i, p);
}
i++;
}
return 0;
}
And this works! It tries every possible value of i, which is pretty inefficient, but due to the properties of prime factorization, it's okay. It tries them in order, so it will always have weeded out all lower prime factors first, so none of the non-prime i's will make it through to get printed as a factor.
To do what I guess you were trying to do, we have to rearrange the code. The basic algorithm is: for each i, if it's prime, see how many times it divides the running n.
#include <stdio.h>
int main()
{
int i = 2, p, c, n;
scanf("%d", &n);
while (n > 1)
{
/* see if i is prime */
c = 1;
for (int d = 2; d <= i / 2 + 1; d++)
if (i % d == 0 && i % 2 != 0)
{
c = 0;
break;
}
if (c == 1) /* if i is prime */
{
p = 0;
while (n % i == 0) /* count how many times i is a factor */
{
p = p + 1;
n = n / i;
}
if (p != 0)
printf("%d %d\n", i, p);
}
i = i + 1;
}
return 0;
}
The primality test is still pretty crude (that line if (i % d == 0 && i % 2 != 0) is fishy), but it seems to work. I suspect it's still wasteful, though: if you're generating all possible trial divisors to factorize n, there's probably a better way than running a full primality test on each i, from scratch.
One popular shortcut is to have i run through 2,3,5,7,9,11,13,... (that is, 2 plus all the odd numbers). Building on that idea, I once wrote some code that uses a more complicated sequence of increments so that it ends up using 2, 3, 5, and then every odd number that isn't a multiple of 3 or 5. I suspect (but I haven't measured) that wastefully using some number of non-prime trial divisors i might end up being less wasteful than positively confirming that each trial divisor is strictly prime.
But if you really care about efficiency, you'll have to abandon this obvious but still rather brute-force technique of blindly trying all the trial divisors, and move to something more sophisticated like elliptic curve factorization. What we're doing here is trial division, which as Wikipedia notes is "the most laborious but easiest to understand of the integer factorization algorithms".

Random number generation in my implementation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Is this implementation of random number generation wrong?
int random_number(int l, int u)
{
int num;
num = rand()%u;
if (num<l && num>u)
{
while(num<l && num>u)
{
num = rand()%u;
}
}
return num;
}
This is not giving me the correct answer.
If I try random_number(4,8); it generates numbers like 0,1,2 etc.
Assuming u means upper and l means lower, then it is wrong. Try this:
int random_number(int l, int u) {
int num = rand() % (u - l);
return num + l;
}
Consider the lines.
int random_number(int l, int u)
num = rand()%u // result 0, 1, 3, .... 7
if (num<l && num>u)
random_number(4,8);
Code needs to follow the if() when num <4 and num > 8. An int cannot both be less than 4 and greater than 8 at the same time.
The usual idiom is
int random_number(int lower, int upper) {
int num;
num = rand()%(upper - lower + 1) + lower;
return num;
}
Extra code is needed to cope/detect upper < lower, upper - lower >= RAND_MAX

Wrong output for prime numbers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
#include <stdio.h>
int main()
{
int i, n, c, p;
printf("enter\n");
scanf("%d", n);
c = find(n);
if (c == 1)
{
printf("no. is not prime");
}
else
{
printf("no. is prime");
}
}
find(int n)
{
int i = 2, p;
while (i < n)
{
p = n % i;
printf("value of p%d", p);
if (p == 0)
{
return 1;
}
i = i + 1;
}
return 2;
}
....................................
Above program giving me 'not a prime number' output for all inputs...also the value of p is always zero and this shouldn't be the case...
Please help...badly stuck...
Your scanf() call must take the address of n. Furthermore you primality test fails for numbers smaller than 2. It is also better to return non-zero for true, zero otherwise, so that the value can directly be tested with if. And you should find a better name than find.
Try something like this:
#define TRUE 1
#define FALSE 0
int is_prime (int n)
{
int i;
if (n < 2)
return FALSE;
for (i = 2; i < n; i++) {
if (n % i == 0) {
return FALSE;
}
}
return TRUE;
}
int main()
{
int n;
printf ("enter number: ");
scanf ("%d", &n);
if (is_prime (n)) {
printf ("number is prime.\n");
}
else {
printf("number is not prime.\n");
}
return 0;
}
Various improvements are possible but I wanted to stay as close to your code as possible.
This looks like a student exercise so let me start by suggesting that the debugger is your friend. :)
Having said that, you may want to review the Sieve of Eratosthenes and leverage Wikipedia for a source of some good test content.
As already suggested, there are loads of potential improvements... I'd modify your "find" function to be more clear as follows:
bool IsPrime(unsigned int n)
{
unsigned int nCounter = 2;
while (n % nCounter++);
return (nCounter > n);
}
Prime's can't be negative and since you're asking a "TRUE/FALSE" question, the name and return type should enforce that contract.
Several issues:
scanf("%d", n); should be scanf("%d", &n); - you need to pass the address of n so scanf can update it (note that you risk a runtime error,
since the value of n most likely isn't a valid address value);
Implicit typing of functions such as find(int n) {...} is no longer supported as of the C99 standard, and it was never good practice to begin with. You should (and for C99 and later, must) provide a type specifier along with the function name in both function declarations and function definitions - int find( int n ) {...};
Similar to 2, a function declaration must be visible before a function is called; the simplest way to accomplish this is to move the function definition above the definition for main. If you don't want to do that, then you need to add the declaration int find(int n); somewhere before find is called.
Note that you can speed up the primality test in a couple of ways. First, you can skip testing against even factors; if a number is divisible by a multiple of 2, then it's divisible by 2, and you would have already checked for that. Secondly, you don't need to test all factors up to n - 1; you only need to test factors up to the square root of n. You can put that all together like so:
if ( n < 2 )
return 0; // zero indicates false
if ( n == 2 )
return 1; // non-zero indicates true
int result = n % 2;
for ( int i = 3; result && i * i <= n; i += 2 ) // loops as long as result
result = n % i; // is non-zero, only tests
// against odd numbers up to
return result; // sqrt(n)

gcc seems to compile my code wrong? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am rather new in C and i was trying to solve some exercises in my textbook and encountered a wierd Problem. although my Task is undeniably easy the program just wont work right. after some Trials it seems that the fault is on the Compiler but as much as this sounds unreasonable its the only justification i can bring up
without any further delay here is the code
#include <stdio.h>
double power(double n, int p);
int main(void)
{
double x, xpow;
int exp;
printf("Enter a number and the positive integer power");
printf(" to which\nthe number will be raised. Enter q");
printf(" to quit.\n");
while (scanf("%lf%d", &x, &exp) == 2)
{
xpow = power(x,exp);
printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
printf("Enter next pair of numbers or q to quit.\n");
}
printf("Hope you enjoyed this power trip -- bye!\n");
return 0;
}
double power(double n, int p)
{
double pow = 1;
int i ;
if ( n == 0 && p == 0)
{
printf("0 to zeroth power is undefined\nwe will use therefor 1 instead\n");
p = 1 ;
}
if (p >= 0)
{
for (i = 1 ; i <= p ; i++);
pow *= n ;
}
else
{
for (i = -1 ; i >= p ; i--);
pow *= 1/n ;
}
return pow;
}
the programs intent is clear the problem is when I input some test cases the output is wrong
like
(5 2)
the output should be 25 but I get 5
(5 6)
the output should be 15625 but i get 5
after examining this problem with gdb I found that instead of initializing i to 1 it is initialized to 3 for no obvious reason and with the second input i is initialized to 7
i want to know why
I'm using gcc.
Why do you blame the compiler, I would blame my eyes first you have an extra semicolon in both your for loops
for (i = 1 ; i <= p ; i++);
change it to
for (i = 1 ; i <= p ; i++)

Resources