I wrote a C program to find out the prime numbers in a given parameter. But for the same input and output, the program has different execution times.
#include <stdio.h>
int main(int argc, char const *argv[])
{
int n,p,k;
scanf("%d", &n);
int prime[n+1];
for (p = 2; p <= n; ++p)
{
if (prime[p]!=-1)
{
for (int i = p*2,k=2; i < n; k++,i=k*p)
{
prime[i]=-1;
}
}
}
for (int i = 1; i < n ; ++i)
{
if (prime[i]!=-1)
{
printf("%d ",i );
}
}
return 0;
}
What you are measuring is the time it takes the user to type the input, i.e. 200.
Calculating the result after the input is given will not take 2 to 5 sec on any modern computer.
It is true that "the computer may be doing other things" and therefore give varying execution time - but that won't give you a 3 sec increase in code like this.
To make the measurement more reliable, you need to "remove" the user input, i.e. remove the scanf.
Instead of scanf you should give the value of n as a command line argument.
Use code like
// scanf("%d", &n); Dont use scanf but use lines like the two below.
if (argc < 2) exit(1); // user error - no number given
n = atoi(argv[1]); // convert command line arg to integer
And start the program like:
test2.exe 200
Now the measured time will be much smaller than 2-5 sec and you won't see execution time vary so much.
Note: While atoi is simple to use, it's in general better to use strtol
The execution of a program on an environment is not dependent only on the code but on some other environment variables such as CPU load.
CLOCKS_PER_SEC is a constant which is declared in <time.h>. To get the CPU time used by a task within a C application, use:
clock_t begin = clock();
/* Do the work. */
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
For your program, You can probably check the
CPU Time took on input.
CPU Time is taken to generate Prime Number
...... and so on
#include <stdio.h>
#include<time.h>
int main(int argc, char const *argv[])
{
int n,p,k;
clock_t t , t1, t2;
t = clock();
scanf("%d", &n);
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("Took %f seconds to take the input\n", time_taken);
t2 = clock();
int prime[n+1];
for (p = 2; p <= n; ++p)
{
if (prime[p]!=-1)
{
for (int i = p*2,k=2; i < n; k++,i=k*p)
{
prime[i]=-1;
}
}
}
t2 = clock() - t2;
double time_taken2 = ((double)t2)/CLOCKS_PER_SEC; // in seconds
printf("Took %f seconds for generating the prime number \n", time_taken2);
for (int i = 1; i < n ; ++i)
{
if (prime[i]!=-1)
{
printf("%d ",i );
}
}
return 0;
}
Output:
200
Took 0.000075 seconds to take the input
Took 0.000004 seconds for generating the prime number
1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 1
13 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
The time is depended on your CPU load. For details please visit here
Related
I am practicing arrays now and in this program I am trying to get prime numbers through this procedure called Sieve of Eratosthenes. But my program does not end. It keeps on running. I thought my netbeans might be broken or something but then it run other programs just fine.
My output is an array from 1 to 100 and after that program keeps on running until I terminate it manually.
so please have a look and tell me what am I doing wrong here ?
Please click link below to see the output.
#include <stdio.h>
int main()
{
int num[100], a, c, b;
//initializing Array
for(a = 0; a <= 99; a++)
{
num[a]=a+1;
}
printf("your array \n");
for(a = 0; a <= 99; a++)
printf(" %d",num[a]);
//Applying Condition
for(a = 1; a < 99; a++)
{
if(num[a]==0)
continue;
else
for(b = 2; b < 100; b++)
{
num[(num[a] * b) - 1] = 0;
}
}
//New Array
printf("\n new array\n");
for(a = 0; a <= 99; a++)
{
if(num[a][enter image description here][1]!=0)
printf("%d ",num[a]);
else
continue;
}
return 0;
}
here is the link to output I get. Array is in one line so cannot show all upto 100.
Your b loop is wrong. An alternative is :
for (b = 2 * num[a]-1; b < 100; b += num[a])
num[b] = 0;
The math would have been a little less obtuse if you would have just used a 0-value in slot num[0], but it is what it is. Your original code was easily breaching the declared size of your array by building a num index from the product of b * num[a], which can work, but only for products below 100, which you weren't guarding against. The alternative above addresses that problem.
Changing that, your program produces the following output for the second number list:
1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
I need to write a program which prints the conversion table from feet and inches to centimetres. The numbers printed in row i (counting from zero), column j (counting from zero) of the table should be the cm equivalent of i feet and j inches. i should go from 0 to 7, and j from 0 to 11. Each column should be five characters wide, and the cm figures should be rounded to the nearest integer.
The example of required output is given below:
0 3 5 8 10 13
30 33 36 38 41
61 64 66 69 71
91 94 97 99 102
The code I have prints only one row of inches and column of feet but I don't know how to make into table without producing lots of irrelevant repetitions.
The code is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int i,j;
int cm,p;
for (i=0; i<= 11; i++) {
cm =round(i * 2.54);
printf ("%5d",cm);
}
for (j=0; j<=7; j++) {
p =round(j* 12.0 * 2.54);
printf ("%5d\n",p);
}
return 0;
}
This produces:
0 3 5 8 10 13 15 18 20 23 25 28 0
30
61
91
122
152
183
213
What am I doing wrong?
You have one loop after the other. What you need to do is run through the inches loop every iteration of your feet loop. What you get is nested loops:
#include <stdio.h>
int main()
{
for (int feet = 0; feet <= 7; ++feet) {
for (int inches = 0; inches < 12; ++inches) {
int microns = (feet * 12 + inches) * 25400;
int rounded_cm = (microns + 5000) / 10000;
printf("%5d", rounded_cm);
}
puts("");
}
}
I've made some other changes in my version; you're encouraged to study it and understand why it does what it does (read the man page for puts(), for example). Don't just copy it and hand it in - it will be obvious it isn't your code.
An alternative approach is to use a single loop (in inches), and insert a newline when we reach the 11th inch in each foot:
#include <stdio.h>
int main()
{
for (int i = 0; i < 96; ++i) {
printf("%4d%s",
(i * 25400 + 5000) / 10000,
i%12==11 ? "\n" : " ");
}
}
(You'll want to give meaningful names to your constants; the above is written in a "code-golf" style).
Whatever you do, don't be tempted to avoid multiplying by instead adding 2.54 repeatedly in the loop. Floating-point numbers are not exact, and addition will accumulate the error.
OP needs to put the "inches" loop inside the "foot" loop as well answered by others. #Toby Speight #VHS
Code could do its "round to nearest" via the printf() statement by using "%5.0f" to control the output width and rounding.
Let code use foot/inch instead of i/j #KevinDTimm for clarity.
#include <stdio.h>
#define INCH_PER_FOOT 12
#define CM_PER_INCH 2.54
int main(void) {
// go from 0 to 7, and ...
for (int foot = 0; foot <= 7; foot++) {
// from 0 to 11
// for (int inch = 0; inch < INCH_PER_FOOT; inch++) { is more idiomatic
for (int inch = 0; inch <= 11; inch++) {
printf("%5.0f", (foot * INCH_PER_FOOT + inch) * CM_PER_INCH);
}
puts("");
}
}
Output
0 3 5 8 10 13 15 18 20 23 25 28
...
213 216 218 221 224 226 229 231 234 236 239 241
You are running your loops backwards. First you need to run through feet and then through inches. But you are having it the other way round. Check the following snipped and compare it with your code and try to understand what's wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h> // for rounding of a number
int main()
{
int i,j;
int cm,p;
for(i=0; i<=7;i++) {
for(j=0;j<=11;j++) {
cm = round(i*30.48 + j*2.54);
printf ("%5d",cm);
}
printf("\n");
}
return 0;
}
This code here is is meant to grab random numbers (temperatures) and create a table with the corresponding hour in which the temperature was recorded. Here is an example of the output I am supposed to be receiving.
Temperature Conditions on October 9, 2015:
Time of Day Temperature in degrees F
0 85
1 80
2 97
3 90
4 68
5 75
6 77
7 98
8 97
9 62
etc...
Maximum Temperature for the day: <whatever> Degrees F
Minimum Temperature for the day: <whatever> Degrees F
Average Temperature for the day: <whatever.whatever> Degrees F
My problem is that when I run the code a dialog box appears and says the program has stopped working and I don't quite know why.
All the help will be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
int GetValue(int[]);
int main() {
int x, n, max = 0,min = 100, ArrayNumMax, ArrayNumMin, temperature[25];
float sum;
float average;
int num[25];
printf("Temperature Conditions on October 9, 2015:\nTime of Day \tTemperature in Degrees F\n");
for (x = 0; x <= 24; x++) {
//if statements to get min and max
temperature[x] = GetValue(temperature);
if (temperature[x] > max) {
max = temperature[x];
ArrayNumMax = x;
}
if (temperature[x] < min) {
min = temperature[x];
ArrayNumMin = x;
}
printf("\t%d\t\t\t\t\t%d\n", x,temperature[x]);
}
//prints statements
printf("\nMidnight\t\t\t\t%d\n\nMaximum Temperature for the day: %d Degrees F at %d\nMinimum Temperature for the day: %d Degrees F at %d\n", temperature[12],max,ArrayNumMax, min, ArrayNumMin);
//adds up all temps
sum=0;
for (x=0;x<25;x++){
sum=(sum+temperature[x]);
}
//prints and creates average
average=sum/25;
printf("Average Temperature for the day: %.2f Degrees F\n",average);
return 0;
}
//gets values and puts them into array
int GetValue(int value[]) {
int x, temp[x];
temp[x] = (rand()%(100-60+1))+60;
return temp[x];
}
1
What are you doing in your GetValue function?
int GetValue(int value[]) {
int x, temp[x]; // create an array of undeclared amount x....
temp[x] = (rand()%(100-60+1))+60; // at invalid memory set it to this value.
return temp[x]; // then return this memory that I have no control over
}
Scrap this and go with this...
void GetValue(int value[], int x) {
value[x] = (rand()%(100-60+1))+60;
}
Also above the main change
int GetValue(int[]);
to
void GetValue(int a[], int b);
Then in your main
//if statements to get min and max
GetValue(temperature, x);
if (temperature[x] > max) {
Also you should look into preprocessor macros.
Read about them here. http://www.tutorialspoint.com/cprogramming/c_preprocessors.htm
such as #define
#define array_size 25
int array[array_size];
Then if you change your code and instead of 25 you need 50 then just change it once.
Two error :
x in GetValue is not initialized so temp[x] has cross the border , so program encounter a segmentation fault.
When you define temp[x], x's value is undefine ,and temp exceed program's stack.
The right one maybe like this:
int GetValue(int value[])
{
int x;
x=1;
int temp[x];
temp[x-1] = (int)((rand()%(100-60+1))+60);
return temp[x-1];
}
The result shows that :
Temperature Conditions on October 9, 2015:
Time of Day Temperature in Degrees F
0 65
1 96
2 60
3 83
4 67
5 79
6 66
7 92
8 83
9 77
10 87
11 66
12 77
13 66
14 68
15 82
16 74
17 79
18 63
19 73
20 86
21 70
22 80
23 81
24 80
Midnight 77
Maximum Temperature for the day: 96 Degrees F at 1
Minimum Temperature for the day: 60 Degrees F at 2
Average Temperature for the day: 76.00 Degrees F
I want to find prime numbers with multithreading and using Sieve of E. function.I write some piece of codes. If the program will run, the user enter a max number and thread number. The program should create threads that given thread number. The program find all prime numbers until the max number. Each thread must check one prime number.
My program doesn't find prime numbers. I write checkPrime function and crossout functions for finding prime numbers efficiently. But it doesn't work. So, I can't check my threads work correctly or not. How can I implement checkPrime function?
There are 3 functions. crossout is for Sieve E. method. checkPrime is for checking is a number prime or not. worker is for thread's function. Each thread must check one prime number.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#define MAX_N 100000000
#define MAX_THREADS 25
// global values
int threadNumber;
int largestNumber;
int isPrime;
int nthreads, // number of threads (not counting main())
prime[MAX_N + 1],
n, // in the end, prime[i] = 1 if i prime, else 0
nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
void crossout(int a) {
int i, j, check;
for (i = 2; i < largestNumber; i++)
prime[i] = 1;
for (i = a; i < largestNumber;)
if (prime[i])
for (j = i; i * j < largestNumber; j++)
prime[i * j] = 0;
}
int checkPrime(int a) {
int i;
for (i = 2; i <= a; ++i) {
if (a % i == 0) {
isPrime = 1;
return isPrime;
break;
} else
isPrime = 2;
crossout(a);
return isPrime;
}
}
void* workerThread(void* t) {
int lim, base;
long i, j;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n", tid);
while (1) {
pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase++;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
if (prime[base]) {
checkPrime(base);
// log work done by this thread
}
}
if (checkPrime(base) == 2)
printf("Thread %ld done. Prime = %d\n", tid, base);
pthread_exit((void*) t);
}
return NULL;
}
//main function with two parameters :argc and argv
int main(int argc, char** argv) {
threadNumber = argv[3];
largestNumber = argv[1];
int i;
pthread_t thread[threadNumber];
int rc;
long t;
void* status;
for (t = 0; t < threadNumber; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, workerThread, (void*)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (t = 0; t < threadNumber; t++) {
rc = pthread_join(thread[t], (void*)&t);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld \n", t);
}
}
You are trying to mix two different methods for finding prime numbers. You don't need to use both the iterative division method and the sieve of Eratosthenes. This shows a way of implementing the sieve. Even numbers are ignored in the sieve but treated as special cases in isprime(). But it won't help you find a multi threaded solution, because you can't just hand over different numbers to different threads - each prime builds on the work of the previous prime, starting with the assumption that 3 is prime.
// Sieve of Eratosthenes
#include <stdio.h>
#include <stdlib.h>
#define LIMIT 200
char sieve[LIMIT] = { 1, 1, }; // 1 for not-prime
int isprime(unsigned n)
{
if(n <= 2) // special cases
return sieve[n] == 0;
if(n % 2 == 0) // even numbers are not prime
return 0;
if(n >= LIMIT) // test range
exit(1);
return sieve[n] == 0;
}
int main(void)
{
unsigned n, p;
for(n=3; n<LIMIT; n+=2) { // odd numbers only
if (sieve[n] == 0) { // if n is prime
for(p=n*n; p<LIMIT; p+=n*2) { // ignore even numbers
sieve[p] = 1; // not primne
}
}
}
printf("Prime numbers are:\n");
for(n=0; n<LIMIT; n++) { // check all numbers
if (isprime(n)) { // if n is prime
printf("%-4d", n);
}
}
printf("\n");
return 0;
}
Program output:
Prime numbers are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199
I'll now show an iterative division method. Once again, even numbers are treated as special cases. I don't often write multi threaded C code, so I can't help you with that. But I hope you can build on this second example to make a multi threaded solution.
// iterative division
#include <stdio.h>
#include <math.h>
#define LIMIT 200
int isprime(unsigned n)
{
unsigned s, i;
if(n <= 1)
return 0;
if(n == 2)
return 1;
if(n % 2 == 0) // no even numbers
return 0;
s = (unsigned)sqrt(n); // limit the loop
for(i=3; i<=s; i+=2) // odd numbers only
if (n % i == 0)
return 0;
return 1;
}
int main(void)
{
unsigned n;
printf("Prime numbers are:\n");
for(n=0; n<LIMIT; n++) { // check all numbers
if (isprime(n)) { // if n is prime
printf("%-4d", n);
}
}
printf("\n");
return 0;
}
Program output:
Prime numbers are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199
There are some pitfalls in both of the above examples when working with larger numbers, but I'll leave them for you to discover.
This is modified version of Sieve of Eratosthenes which is the very simple, interesting and fast. Understand its working as I have tried to explain it using comments. Actually try to understand the run-time allocation of array size to avoid defining a large MAX value and try to code simple by analyzing your algorithm and applying good mathematics along with smart coding knowledge.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int *arr;
int count=0,i=3,j,n;
arr=(int*)malloc(count+1*sizeof(int)); //set array size to 1
arr[count++]=2; //stored 2 as array first element
printf("Find all prime numbers upto :: ");
scanf("%d",&n); //n is the number up to which prime numbers are required
here:
{
while(i<=n) //start with i=3
{
j=0;
while(arr[j]<=sqrt(i)) //till array element value is less than or equal to root of number under checking
{
if(i%arr[j]!=0) //if remainder is not zero check divisibility with next array element
j++;
else
{
i++; //if remainder is zero then start checking for another number
goto here;
}
}
printf("%d, ",arr[count-1]); //printing the number which was proved as prime last time
arr=(int *)realloc(arr,(count+1)*sizeof(int)); //increasing array size by 1
arr[count++]=i; //newly proved prime is stored as next array element
i++;
}
printf("%d, ",arr[count-1]); //print last number proved as prime
}
I have a program that outputs a huge array of integers to stdout, each integer in a line. Ex:
103
104
105
107
I need to write another program that reads in that array and fill up the spaces where the number isn't an increment of 1 of the previous number. The only different between numbers is going to be 2 (105,107), which makes it easier.
This is my code to do that logic:
printf("d",num1);
if ((num2-num1) != 1)
numbetween = num1 + 1;
printf("%d", numbetween);
printf("%d", num2);
else(
printf("%d",num2);
)
So the output of this program will now be:
103
104
105
106
107
My issue is reading the numbers. I know I can do while (scanf("%hd", &num) != EOF) to read all the lines one at a time. But to do the logic that I want, I'm going to need to read two lines at a time and do computation with them, and I don't know how.
You could always just read the first and last numbers from the file, and then print everything in between.
int main( void )
{
// get the first value in the file
int start;
if ( scanf( "%d", &start ) != 1 )
exit( 1 );
// get the last value in the file
int end = start;
while ( scanf( "%d", &end ) == 1 )
;
// print the list of numbers
for ( int i = start; i <= end; i++ )
printf( "%d\n", i );
}
Read first num then add missing if needed when you read next int
#include <stdio.h>
#include <stdlib.h>
int main()
{
int previous = 0;
int num;
scanf("%hd", &previous);
while (scanf("%hd", &num) != EOF) {
for (int i = previous; i < num; i++) {
printf("%d\n" , i);
}
previous = num;
}
printf("%d\n" , previous);
return 0;
}
this input
100
102
103
105
107
110
returns this output
100
101
102
103
104
105
106
107
108
109
110
While you can read the first and last, to fill the range, what you are really doing is finding the min and max and printing all values between them inclusively. Below the names are left first and last, but they represent min and max and will cover your range regardless whether the values are entered in order. Taking that into consideration, another approach insuring you cover the limits of the range of int would be:
#include <stdio.h>
int main (void) {
int num = 0;
int first = (1U << 31) - 1; /* INT_MAX */
int last = (-first - 1); /* INT_MIN */
/* read all values saving only first (min) and last (max) */
while (scanf (" %d", &num) != EOF) {
first = num < first ? num : first;
last = num > last ? num : last;
}
/* print all values first -> last */
for (num = first; num <= last; num++)
printf ("%d\n", num);
return 0;
}
Input
$ cat dat/firstlast.txt
21
25
29
33
37
41
45
49
53
57
61
65
69
73
77
81
85
89
93
97
101
Output
$ ./bin/firstlast < dat/firstlast.txt
21
22
23
24
25
26
27
28
29
<snip>
94
95
96
97
98
99
100
101
Note: you can change the types to conform to your expected range of data.