Sum of primes below 2 million - c

What am i doing wrong here?
#include<stdio.h>
int main(){
int i,count;
long long int sum = 0, num;
for(num = 1; num <= 1000; num++){
count = 0;
for(i = 2; i <= num / 2; i++){
if(num % i == 0){
count++;
break;
}
}
if(count == 0 && num != 1)
sum = sum + num;
}
printf("Sum of prime numbers is: %d ", sum);
return 0;
}
I tried to make a program that outputs the sum of all primes below nth number, n being 2 million however when i try to run it, there is a slight delay and it outputs nothing... it works well enough for small numbers like 1000 or 100 but big numbers it just does not output anything.There are no error or bugs that i know of either. (please help, i know nothing, so guide this young one)

The above program is fine, but it is possible to further reduce the time complexity and make it faster. The better approach is to use sieve of eratosthenes algorithm.You can read about it here http://www.geeksforgeeks.org/sieve-of-eratosthenes/
The program for your problem is
#include <bits/stdc++.h>
using namespace std;
void SieveOfEratosthenes(long long int n)
{
bool prime[n+1];
memset(prime, true, sizeof(prime));
for (long long int p=2; p*p<=n; p++)
{
if (prime[p] == true)
{
for (int i=p*2; i<=n; i += p)
prime[i] = false;
}
}
long long sum=0;
for (int p=2; p<=n; p++)
if (prime[p])
sum+=p;
cout << sum << " ";
}
int main()
{
int n = 2000000;
cout << "sum of prime numbers less then 2000000 is :" << endl;
SieveOfEratosthenes(n);
return 0;
}
Please let me know if you face difficulty in understanding the program.Note: You can also use Segmented seive to further reduce the time complexity

#include<stdio.h>
#include<math.h>
int main(){
int i,count;
long long int sum=0, num;
for(num = 1;num<=1000000;num++){
count = 0;
for(i=2;i<=sqrt(num);i++){ //change here
if(num%i==0){
count++;
break;
}
}
if(count==0 && num!= 1)
sum = sum + num;
}
printf("Sum of prime numbers is: %lld ",sum); //and here
return 0;
}
Some simple maths, while checking for prime, check up to square root of a number. And in printf() the format specifier for long long int is %lld not %d.

Related

How to convert floating-point in for-loop to integer in C, for correct calculation

I'm trying to understand C better. In an exercise I had to find out what is wrong about the following code example.
#include <stdio.h>
int main() {
int count;
float sum;
float i;
sum = 0, count = 0;
for (i = 1000; i <= 1000.04; i += .01) {
sum += i;
count++;
}
printf("Sum: %f, Count: %d\n", sum, count);
return 0;
}
I found out that it's a bad idea to use floating-point in loops because it causes problems bsince it's not accurate. Next step is to rewrite the code, so it does the same thing but without using floating-point in the loop. I'm stuck on this task, I don't know how to replace i <= 1000.04. For i += .01 I guess I could replace it with i++ and divide it with 100 somewhere else.
Any ideas how to fix it properly?
#include <stdio.h>
int main() {
int count;
float sum;
int i;
sum = 0, count = 0;
for (i = 100000; i <= 100004; i++) {
sum += i;
count++;
}
printf("Sum: %f, Count: %d\n", sum/100, count);
return 0;
}

Euler 10, Sum of primes to 2000000

I have a problem with my algorithm. I can't find where a go wrong in the task below.
Description:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
Here is my solution in C:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
bool *numbers = (bool *)malloc(sizeof(bool) * 2000000);
unsigned long run = 1;
while (run < 2000000) {
numbers[run] = true;
run++;
}
unsigned long sum = 0;
for (long i = 2; i < 2000000; i++) {
if (numbers[i] == true) {
for (long x = 2 * i; x < 2000000; x += i) {
numbers[x] = false;
}
}
}
run = 0;
while (run < 2000000) {
if (numbers[run] == true) {
sum = sum + run;
}
run++;
}
printf("%d\n", sum-1); // cause 1
free(numbers);
return 0;
}
Thanks for help!!!
The problem in your code is you do not use the correct printf conversion specifier for sum that has type unsigned long: you should write:
printf("%lu\n", sum);
The result, 142913828923 exceeds the range of 32-bit integers, so you should actually use a larger type such as long long which is guaranteed to have at least 63 value bits. The last loop should start from 2 to avoid counting 1 as a prime number.
Here is a modified version with some improvements:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
int limit = 2000000;
bool *numbers = (bool *)malloc(sizeof(bool) * limit);
if (numbers == NULL) {
printf("not enough memory\n");
return 1;
}
for (int run = 0; run < limit; run++) {
numbers[run] = true;
}
for (long long i = 2; i * i < limit; i++) {
if (numbers[i] == true) {
for (long long x = i * i; x < limit; x += i) {
numbers[x] = false;
}
}
}
long long sum = 0;
for (int run = 2; run < limit; run++) {
if (numbers[run] == true) {
sum = sum + run;
}
}
printf("%lld\n", sum);
free(numbers);
return 0;
}
You can try something along these lines:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long int i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
char *primes; // only needs to be used as a flag holder
primes = malloc(sizeof(char)*limit); // flag of is prime or not
if(primes==NULL) {
perror("main, malloc");
return(-1);
} // else
for (i=2;i<limit;i++) // set the flags to True to start
primes[i]=1;
for (i=2;i<limit;i++) // now go through all combos
if (primes[i]) // already know; no need
for (j=i;i*j<limit;j++) // has i and j as factors
primes[i*j]=0; // not prime
for (i=2;i<limit;i++) // now add them up
if (primes[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long or %llu for long long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
You can also invert the search to flag composite numbers rather than primes by using calloc vs malloc and save a loop (Thanks to Anti Haapala):
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(){
unsigned long i,j;
unsigned long long sum=0; // the sum is potentially large
unsigned long cnt=0;
int limit=2000000; // the limit for the sums
bool * composite = (bool *)calloc(limit, sizeof(bool));
if(composite==NULL) {
perror("main, calloc");
return(-1);
}
for (i=2;i<limit;i++) // now go through all combos
if (!composite[i])
for (j=i;i*j<limit;j++) // has i and j as factors
composite[i*j]=true; // composite; not prime
for (i=2;i<limit;i++) // now add them up
if (!composite[i]) {
sum+=i;
cnt++;
}
// report what was found; note %lu for long
printf("There are %lu primes less than %d with a sum of %llu",
cnt, limit, sum);
return 0;
}
Both print:
There are 148933 primes less than 2000000 with a sum of 142913828922
Note:
Use a long long for the sum which is guaranteed to be 64 bits. While a long may be 32 or 64 bits and an int may be as short as 16 bits. See C data types
Make sure the printf type and length specifiers are correct given the data types being printed.

The following program "Counting consecutive 1's of a binary no" shows different ans when input goes more than 8-digit value?

I have tried different inputs and when it exceeds a 7 or 8 digit value it just shows some wrong answers as outputs but it worked fine with most of my cases.
#include <stdio.h>
#include <stdlib.h>
int bin(unsigned long long int n){//gave function for binary convertion
if(n==0)
return 0;
else
return (n%2+10*bin(n/2));
}
int main()
{
unsigned long long int n,x;/*I even gave high digit data type*/
int i, v, count=0, max=0;
scanf("%llu",&n); /*if input is >8-digit output is wrong*/
x = bin(n);
v = floor(log10(x))+1; /*Its length*/
int a[v];
for(i = v-1; i >= 0; i--){ /*string it in array*/
a[i] = x%10;
x = x/10;
}
for(i = 0; i < v; i++){
if(a[i] == 0){
count = 0;}
else{
count++;}
if(max < count){
max = count;}
}
printf("%d",max);/*I gave 99999999 output is 8 but its shows 9*/
}
Your program has a number of problems. Here is one example:
int bin(unsigned long long int n){
^^^
The function returns an int so the calculation will overflow for even small numbers:
printf("%d\n", bin(1023)); // will print 1111111111 (fine)
printf("%d\n", bin(1024)); // will/may print 1410065408 (ups - very bad)
Even if you change to
unsigned long long int bin(unsigned long long int n){
overflow will happen soon.
In I'll recommend that you look directly into the binary pattern of the number using the & operator.
I'll not solve the complete task for you but here is some code that may help you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
size_t t = 1;
size_t limit;
size_t n;
if (scanf("%zu", &n) != 1)
{
printf("Illegal input\n");
exit(1);
}
limit = 8 * sizeof n; // Assume 8 bit chars
for (size_t i = 0; i < limit; ++i)
{
if (n & t)
{
printf("Bit %zu is 1\n", i);
}
else
{
printf("Bit %zu is 0\n", i);
}
t = t << 1;
}
return 0;
}

Calculating Arithmetic and Geometric mean by introducing numbers until 0 is pressed

I have to calculate the arithmetic and geometrical mean of numbers entered by the user in C language. The algorithm works fine, but I don't know how to do the enter numbers until 0 is pressed part. I have tried many things but nothing works. Here is what I have tried to do until now. Thanks for the help.
int main() {
int n, i, m, j, arr[50], sum = 0, prod = 1;
printf("Enter numbers until you press number 0:");
scanf("%d",&n);
while (n != 0) {
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
sum = sum + arr[i];
prod = prod * arr[i];
}
}
int armean = sum / n;
float geomean = pow(prod, (float)1 / n);
printf("Arithmetic Mean = %d\n", armean);
printf("Geometric Mean = %f\n", geomean);
getch();
}
Your code is asking for the number of values in advance and subsequently reading that many values. That's not what you were asked to do.
You need to ask for numbers in a loop and exit the loop when the number that you read is 0. You don't even need an array:
int n = 0, i, m, j, sum=0, prod=1;
while (1) {
int value;
scanf("%d",&value);
if (value == 0) {
break;
}
sum=sum+value;
prod=prod*value;
n++;
}
int armean=sum/n;
float geomean=pow(prod,(float) 1/n);
You have to break the for loop when value 0 entered; so you should check for arr[i].
While loop is not required.
Please go through below code; this could be help full:
#include <stdio.h>
int main()
{
int n, i, m, j, arr[50], sum=0, prod=1;
printf("Enter numbers until you press number 0:");
for(i=0; i<50; i++)
{
scanf("%d",&arr[i]);
if (arr[i] == 0)
{
break;
}
sum=sum+arr[i];
prod=prod*arr[i];
}
printf ("%d %d\n",sum, prod);
n = i+1;
int armean=sum/n;
float geomean=pow(prod,(float) 1/n);
printf("Arithmetic Mean = %d\n",armean);
printf("Geometric Mean = %f\n",geomean);
getch();
return 0;
}
what dbush said is right, you don't need array and are not asking the number in advance but what he did not tell is how can you find the number of values
int main()
{
int n, sum=0, prod=1, num;
printf("Enter numbers until you press number 0:\n");
for(n=0; ; n++)
{
scanf("%d",&num);
if(num==0)
break;
sum=sum+num;
prod=prod*num;
}
printf("sum is %d \n",sum);
printf("prod is %d \n",prod);
printf("n is %d \n",n);
float armean=sum/n; //why int?
float geomean=pow(prod,(float) 1/n);
printf("Arithmetic Mean = %d\n",armean);
printf("Geometric Mean = %f\n",geomean);
//getch(); why getch(), you are not using turboc are you?
}
There is no need for an array, but you should test if the number entered in 0 after reading it from the user. It would be better also to use floating point arithmetic to avoid arithmetic overflow, which would occur quickly on the product of values.
In any case, you must include <math.h> for pow to be correctly defined, you should test the return value of scanf() and avoid dividing by 0 if no numbers were entered before 0.
#include <stdio.h>
#include <math.h>
int main() {
int n = 0;
double value, sum = 0, product = 1;
printf("Enter numbers, end with 0: ");
while (scanf("%lf", &value) == 1 && value != 0) {
sum += value;
product *= value;
n++;
}
if (n > 0) {
printf("Arithmetic mean = %g\n", sum / n);
printf("Geometric mean = %g\n", pow(product, 1.0 / n));
getch();
}
return 0;
}

prime numbers in a given range

I have to find all the prime numbers between two numbers m and n. (1 <= m <= n <= 1000000000 and n-m <= 100000). I am using sieve of eratosthenes but getting wrong answer. Can anyone help me what is wrong with my code.
#include<stdio.h>
#include<math.h>
int S[100002];
void sieve(long long int m, long long int n)
{
long long int x=sqrt(n);
long long int i,j;
long long int a;
for(i=0;i<=n-m+2;i++)
S[i]=0;
if(m%2==0)
i=m;
else {
i=m+1;
}
for (;i<=n;i+=2){
S[i-m]=1;
}
for (i=3;i<=x;i+=2){
if(i>=m && S[i-m]) continue;
if(i*i>=m)j=i*i;
else {
a = (m-i*i)%(2*i);
if(a==0)j=m;
else
j=m+ (2*i -a);
}
for (;j<=n;j+=2*i){
S[j-m]=1;
}
}
if (m==1)i=1; else i=0;
for (;i<=n-m;i++)
if (!S[i]){
printf("%lld\n",i+m);
}
}
int main(){
int t;
long long int m,n;
scanf("%d\n",&t);
while(t--){
scanf("%lld %lld",&m,&n);
sieve(m,n);
printf("\n");
}
return(0);
}
if(m%2==0)
i=m;
else {
i=m+1;
}
for (;i<=n;i+=2){
S[i-m]=1;
}
Now, what happens if m <= 2? Will 2 be considered prime or not?
You should use loop in main and call prime function.
For performance, I recommend you to avoid using sqrt function because it requires a lot of CPU clocks.
bool isPrime(int number){
if(number < 2) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(int i=3; (i*i)<=number; i+=2){
if(number % i == 0 ) return false;
}
return true;
}
***Change datatype for the range of number (long, long long, etc).
It is the most efficient(Sieve method) way of finding prime number between a range.
Here 1 is not consider as a prime number as a conventionally way.
#include<stdio.h>
#include<string.h>
#define max 10000000
using namespace std;
int main()
{
unsigned long long int i, j, k, m, n;
unsigned long long int* a = new unsigned long long int[max];
scanf("%ul %ul",&m,&n);
for(i = 1;i<=n;i++)
a[i]=i;
a[1] = 0;
for(i=2;(i*i)<=n;i++)
if(a[i]!=0)
for(k=2*i;k<=n;k=k+i)
if(a[k]!=0)
a[k]=0;
for(i =m;i<=n;i++)
if(a[i]!=0)
printf("%ul ",a[i]);
memset(a, 0, sizeof(a));
return 0;
}
#include<stdio.h>
#include<stdlib.h>
void prime(int );
int main(){
int x, end;
printf("Enter end of the range:\n");
scanf("%d", &end);
for(x = 2;x <= end;x++){
prime(x);
}
return 0;
}
void prime(int x){
int j, count = 1;
for(j=2;j <= x;j++){
if(x % j == 0){
count += 1;
//printf("count = %d,x = %d", count, x);
}
}
if(count == 2){
printf("\n%d\n", x);
}
}

Resources