This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
C - determine if a number is prime
Is there any way to test easily in C whether a selected number is prime or not?
The easiest way is writing a loop, like:
int is_prime(int num)
{
if (num <= 1) return 0;
if (num % 2 == 0 && num > 2) return 0;
for(int i = 3; i < num / 2; i+= 2)
{
if (num % i == 0)
return 0;
}
return 1;
}
You can then optimize it, iterating to floor(sqrt(num)).
The fastest way is to precalculate a bit array (indicating prime/nonprime) of all possible integers in the range you're interested in. For 32-bit unsigned integers, that's only 512M, which will easily fit in modern address spaces (and, even if it didn't, it would be a fast file lookup).
This will almost certainly be faster than calculating it via a sieve each time.
You could try to use Sieve of Eratosthenes:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Easily you will find various implementations of this algorithm.
Related
I'm supposed to create a function to find the closest next prime number for a given number, I mean even though the algorithm is badly written and very slow (probably it's the slowest around), but its doing the task, the problem is the program supposed to evaluate my thing refuse it with timeout error, he had given it a bunch of numbers at once and he want them to be all resolved in 10 seconds, so the question is there any improvements you may suggest that could fast forward my poor tortue ? (for is not allowed)
int is_prime(int nb)
{
int i;
/* if negative terminate */
if (nb <= 1)
return (0);
/* start from first prime */
i = 2;
/* primes equals zero only when divisible by 1 and theme-selves */
while (nb % i != 0)
i++;
/* if i divides nb, we see if i is the nb we looking for */
if (i == nb)
return (1);
else
return (0);
}
int find_next_prime(int nb)
{
int i;
i = 0;
/*keep looking for primes one by one */
while (!is_prime(nb + i))
i++;
return (nb + i);
}
The best simple speed improvement is to check divisors up to the square root of n rather than all divisors up to n. This takes the algorithm from O(nb) to O(sqrt(nb)).
Consider is_prime(2147483647). OP's approach takes about 2147483647 iterations. Testing up to about the square root, 46341, is about 46,000 times faster.
// while (nb % i != 0) i++;
// if (i == nb) return (1);
// else return (0);
// While the divisor <= quotient (or until the square root is reached)
while (i <= nb/i) {
if (nb%i == 0) return 1;
i++;
}
return 0;
Avoid a i*i <= nb test as i*i may overflow.
Avoid sqrt(nb) as than involves a host of floating point/int issues.
Note: Good compilers see nearby nb/i; nb%i and compute them both for the time cost of one.
Lots of other improvements are possible, but wanted to focus on a simple one with a big impact. When wanting to improve speed focus on reducing order of complexity O() and not linear improvements. Is premature optimization really the root of all evil?
Your missing the two most common tricks to improve speed.
you only need to check up to square root of the number
once you have check 2, you only need to check every other number from 3 on.
I read here (page 14) that one way to improve the code efficiency for ARM-devices would be to use ARM_compiler specific keywords like __promiseand the folowing sample code is mentioned:
void f(int *x, int n)
{
int i;
__promise((n > 0) && ((n & 7) == 0)); /* My Question: How this line improves efficiency */
for(i = 0; i < n; i++)
{
x[i]++;
}
}
But I don't undrestand how this extra information (the loop index is positive and divisable by 8) improves the efficiency!
could anybody please explain how?
__promise((n > 0) && ((n & 7) == 0));
The binary representation of 7 is 0b111. This tells you that the last 3 bits of n will always be zero. Therefore n must be a multiple of 8. Furtermore n will also be greater than 0.
You thus promise the compiler, that it can safely unroll your loop into blocks of 8, and that it will do at least one iteration.
The compiler could therefore choose to rewrite your code as:
int i = 0;
do
{
x[i+0]++;
x[i+1]++;
x[i+2]++;
x[i+3]++;
x[i+4]++;
x[i+5]++;
x[i+6]++;
x[i+7]++;
} while ((i+=8) != n);
Which will skip a bunch of comparisons.
NEONs VADD instruction will even allow you to optimize this even further: vaddq_s32 would allow you to add the vector (1,1,1,1) to groups of four elements of your array at once. So your compiler could replace that block with two vadd instructions (if it feels you could benefit from that).
This question already has answers here:
How to write log base(2) in c/c++
(14 answers)
Closed 5 years ago.
For example,
Input result
2 N: 1
4 N: 2
8 N: 3
Is there such function that I can directly use in c?
Or is there any quick simple method to get the N?
Mine:
// assume A is not very big
int getN(int A) {
int i = 0;
for(i = 0;;i++) {
if( 1 << i == A ) return i;
}
}
Assuming the input fits in a long, if you don't care much about performance, use log2 to compute the logarithm in base 2 (then cast it to an int) per other answers. BTW your naive getN is practically fast enough (but would loop indefinitely for a 0 input, you could limit that with for(i = 0; i<64; i++) ), and might even be faster than a log2, and you could make it a static inline function (in some header file).
If you are using GCC and if you know that the input is a power of 2 (so has exactly one bit set), you could use the faster __builtin_ffs builtin (find first set bit).
If the number is very large, you want to do arbitrary precision arithmetic. Then use a library like GMPlib.
If you like to use a custom recursive function to get N , use this function. Otherwise go for log of input.
int getN(int num){
if((num/2)==1){
return 1;
}
else if((num%2)!=0){
return 0;
}
else{
return (1 + getN(num/2));
}
}
Sure there is - log2 ( double d )
Use like this:
#include <math.h>
#include <stdio.h>
#define N somenumber
int main(){
int a = 1 << N; // == 2 raised to the power of N
printf("%d", (int)log2((double)a)); // output: N. can leave out the cast, for double format result
return 0;
}
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 5 years ago.
Improve this question
So i recently did a university exam and one of the questions asked us to create a program that would print out the nth number in the tribonacci sequence (1,1,1,3,5,9,17,31...). These numbers were said to go as large as 1500 digits long. I created a recursive function that worked for the first 37 tribonacci numbers. But a stack overflow occurred at the 38th number. The question had warned us about this and said that we would somehow need to overcome this, but i have no idea how. Were we meant to create our own data type?
double tribonacci(int n){
if(n < 4){
return 1;
}else{
return tribonacci(n-3) + tribonacci(n-2) + tribonacci(n-1);
}
}
int main(int argc, char *argv[]){
double value = tribonacci(atoi(argv[1]));
printf("%lf\n", value);
}
This is the solution i wrote under exam conditions, which was within 15 minutes.
The program took the value of n from an input in the command line. We were not allowed to use any libraries except for stdlib.h and stdio.h. So with all that said, how might one create a data type large enough to print out numbers with 1500 digits (since the double data type only holds enough for up until the 37th tribonacci number)? Or is there another method to this question?
You should use some arbitrary-precision arithmetic library (a.k.a. Bigints or bignums) if your teacher allows them. I recommend GMPlib, but there are others.
See also this answer (notably if your teacher wants you to write some crude arbitrary precision addition).
For a development time limited exam solution, I'd definitely go for the quick & dirty approach, but I wouldn't exactly complete it within 15 minutes.
The problem size is restricted to 1500 characters, computing tribonacci indicates that you will always need to carry subresult N-3, N-2 and N-1 in order to compute subresult N. So lets define a suitable static data structure with the right starting values (its 1;1;1 in your question, but I think it should be 0;1;1):
char characterLines[4][1501] = { { '0', 0 }, { '1', 0 }, { '1', 0 } };
Then define an add function that operates on character arrays, expecting '\0' as end of array and the character numbers '0' to '9' as digits in a way that the least significant digit comes first.
void addBigIntegerCharacters(const char* i1, const char* i2, char* outArray)
{
int carry = 0;
while(*i1 && *i2)
{
int partResult = carry + (*i1 - '0') + (*i2 - '0');
carry = partResult / 10;
*outArray = (partResult % 10) + '0';
++i1; ++i2; ++outArray;
}
while(*i1)
{
int partResult = carry + (*i1 - '0');
carry = partResult / 10;
*outArray = (partResult % 10) + '0';
++i1; ++outArray;
}
while(*i2)
{
int partResult = carry + (*i2 - '0');
carry = partResult / 10;
*outArray = (partResult % 10) + '0';
++i2; ++outArray;
}
if (carry > 0)
{
*outArray = carry + '0';
++outArray;
}
*outArray = 0;
}
Compute the tribonacci with the necessary number of additions:
// n as 1-based tribonacci index.
char* computeTribonacci(int n)
{
// initialize at index - 1 since it will be updated before first computation
int srcIndex1 = -1;
int srcIndex2 = 0;
int srcIndex3 = 1;
int targetIndex = 2;
if (n < 4)
{
return characterLines[n - 1];
}
n -= 3;
while (n > 0)
{
// update source and target indices
srcIndex1 = (srcIndex1 + 1) % 4;
srcIndex2 = (srcIndex2 + 1) % 4;
srcIndex3 = (srcIndex3 + 1) % 4;
targetIndex = (targetIndex + 1) % 4;
addBigIntegerCharacters(characterLines[srcIndex1], characterLines[srcIndex2], characterLines[targetIndex]);
addBigIntegerCharacters(characterLines[targetIndex], characterLines[srcIndex3], characterLines[targetIndex]);
--n;
}
return characterLines[targetIndex];
}
And remember that your least significant digit comes first when printing the result
void printReverse(const char* start)
{
const char* printIterator = start;
while (*printIterator)
{
++printIterator;
}
do
{
putchar(*(--printIterator));
} while (printIterator != start);
}
int main()
{
char* c = computeTribonacci(50); // the real result is the array right-to-left
printReverse(c);
}
As said, this is kindof quick & dirty coded, but still not within 15 minutes.
The reason why I use a separate char per decimal digit is mainly readability and conformity to the way how decimal math works on pen&paper, which is an important factor when development time is limited. With focus on runtime constraints rather than development time, I'd probably group the numbers in an array of unsigned long long, each representing 18 decimal digits. I would still focus on decimal digit groupings, because this is a lot easier to print as characters using the standard library functions. 18 because I need one digit for math overflow and 19 is the limit of fully available decimal digits for unsigned long long. This would result in a few more changes... 0 couldn't be used as termination character anymore, so it would probably be worth saving the valid length of each array. The principle of add and computeTribonacci would stay the same with some minor technical changes, printing would need some tweaks to ensure a length 18 output for each group of numbers other than the most significant one.
You require a different algorithm. The code posted cannot suffer from an integer overflow, as it does all its calculations in doubles. So you are probably getting a stack overflow instead. The posted code uses exponential time and space, and at N=38 that exponential space is probably overflowing the stack. Some alternatives, in increasing order of efficiency and complexity:
Use the "memoization" technique to optimize the algorithm you have.
Build up the answer starting by calculating N=4, and iterating upwards. No recursion is then needed.
Do the mathematics (or find someone who can) to get the "closed form solution" that allows direct calculation of the answer. See https://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression for how this works for regular fibonacci numbers.
You will also need a "big number" data structure - see other answers.
You need to replace the + operation with an operator ADD made by yourself and encode BigIntegers as you wish -- there are lots of ways to encode BigIntegers.
So you need to define yourself a datatype BigInteger and the following operations
ADD : BigInteger, BigInteger -> BigInteger
1+ : BigInteger -> BigInteger
2- : BigInteger -> BigInteger
<4 : BigInteger -> boolean
The constants 1,2,4 as BigInteger
and after having replaced these things write a standard function to compute fibb in linear time and space.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Generating Random Numbers in Objective-C
How do I generate a random number which is within a range?
This is actually a bit harder to get really correct than most people realize:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
Attempts that just use % (or, equivalently, /) to get the numbers in a range almost inevitably introduce skew (i.e., some numbers will be generated more often than others).
As to why using % produces skewed results: unless the range you want is a divisor of RAND_MAX, skew is inevitable. If you start with small numbers, it's pretty easy to see why. Consider taking 10 pieces of candy (that we'll assume you can't cut, break, etc. into smaller pieces) and trying to divide it evenly between three children. Clearly it can't be done--if you hand out all the candy, the closest you can get is for two kids to get three pieces of candy, and one of them getting four.
There's only one way for all the kids to get the same number of pieces of candy: make sure you don't hand out the last piece of candy at all.
To relate this to the code above, let's start by numbering the candies from 1 to 10 and the kids from 1 to 3. The initial division says since there are three kids, our divisor is three. We then pull a random candy from the bucket, look at its number and divide by three and hand it to that kid -- but if the result is greater than 3 (i.e. we've picked out candy number 10) we just don't hand it out at all -- we discard it and pick out another candy.
Of course, if you're using a modern implementation of C++ (i.e., one that supports C++11 or newer), you should usually use one the distribution classes from the standard library. The code above corresponds most closely with std::uniform_int_distribution, but the standard library also includes uniform_real_distribution as well as classes for a number of non-uniform distributions (Bernoulli, Poisson, normal, maybe a couple others I don't remember at the moment).
int rand_range(int min_n, int max_n)
{
return rand() % (max_n - min_n + 1) + min_n;
}
For fractions:
double rand_range(double min_n, double max_n)
{
return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}
For an integer value in the range [min,max):
double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale)
I wrote this specifically in Obj-C for an iPhone project:
- (int) intInRangeMinimum:(int)min andMaximum:(int)max {
if (min > max) { return -1; }
int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)}
int random = arc4random() % adjustedMax;
int result = random + min;
return result;
}
To use:
int newNumber = [aClass intInRangeMinimum:1 andMaximum:100];
Add salt to taste
+(NSInteger)randomNumberWithMin:(NSInteger)min WithMax:(NSInteger)max {
if (min>max) {
int tempMax=max;
max=min;
min=tempMax;
}
int randomy=arc4random() % (max-min+1);
randomy=randomy+min;
return randomy;
}
I use this method in a random number related class I made. Works well for my non-demanding needs, but may well be biased in some way.