Trying to learn C I'm toying around a bit with some for loops and sums. I want to compute the sum of the first n natural numbers without using the mathematical formula n(n+1)/2. I have this code for it:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 100;
int sum = 0;
for (int ix = 0; ix <= n; ix++) {
sum = sum + ix;
}
printf("Sum of the first %d natural numbers is %d\n", n, sum);
}
So for n = 100 I get the sum to be 5050, which is correct. I also get correct when I use n = 10000, however if I go for example n = 1000000 then I get the sum = 1784293664 but correct answer should be sum = 500000500000.
Why does my program stop working when n becomes larger and what is that number of the sum being displayed when n = 1000000?
If you want to calculate a sum of natural numbers then instead of the type int use the type unsigned int.
Correspondingly declare the variable sum as having the type unsigned long long int to decrease the risk of overflow.
For example
unsigned int n = 100;
unsigned long long int sum = 0;
for ( unsigned int ix = 1; ix <= n; ix++){
sum = sum + ix;
}
printf("Sum of the first %u natural numbers is %llu\n" , n, sum);
Or you could include the header <inttypes.h> and use the type uintmax_t for the variable sum as it is shown in the demonstrative program below.
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
unsigned int n = 1000000;
uintmax_t sum = 0;
for ( unsigned int ix = 1; ix <= n; ix++){
sum = sum + ix;
}
printf("Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum);
return 0;
}
The program output is
Sum of the first 1000000 natural numbers is 500000500000
Pay attention to that there is no need to introduce the auxiliary variable ix. The loop can look simpler as for example
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
unsigned int n = 1000000;
uintmax_t sum = 0;
while ( n ) sum += n--;
printf( "Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum );
return 0;
}
You are hitting variable type 'int' limit. Try using long data type to store the sum.
int type is too small to contain numbers so huge, so an arithmetic overflow happens on the way up there. What you observe is called undefined behaviour (UB for short), this is what officially happens in C when signed integers overflow (unsigned ones simply rollover to zero and on).
#include<stdio.h>
int main(){
int i=0, sum=0, n=10;
while(i<=n){
printf("%d\n",i);
sum=sum+i;
i++;
}
printf("%d",sum);
return 0;
}
Related
i'm just starting with getting to know C, and i'm now following the cs50 course. i have a question on the following code.
I want to calculate the avarage score of the user input.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int s = get_int("how many scores? ");
int sum = 0;
int score[s];
for(int i = 0; i < s; i++)
{
score[i] = get_int("score: ");
sum = sum + score[i];
}
float avg = sum / s;
printf("avarage: %f\n", avg);
}
So, it prints the avarage, but gets round down to .0000.
Is it because i am using a int to divide by? i have tried several things, like changing int to float, but without result.
How do I solve this?
This is an integer division:
float avg = sum / s;
Which means that 3 / 2 will be 1 (the decimal part is discarded). This will then be stored in avg as 1.f.
You need to make it into a floating point division. You can cast one of the operands to the desired type:
float avg = (float)sum / s;
Now both operands (sum and s) will be converted to float before the actual division takes place and the correct result will be shown, which is 1.5 + some zeroes in the example above.
#Ted's answer (integer division) is the reason your results were not as expected.
For your consideration, I've rewritten your code to be more concise. (The less code there is, the easier it can be to read and understand (as you learn more about C.))
#include <cs50.h>
#include <stdio.h>
int main() // 'void' is unnecessary
{
double sum = 0.0; // make the accumulator floating point
int s = get_int( "how many scores? " );
for(int i = 0; i < s; i++) // no need for braces when...
sum += get_int( "score: " ); // everything happens on one line
/* Above: you may not have seen "+=" before. Find out. Aids clarity */
printf("avarage: %lf\n", sum / s ); // float division result is printed.
}
And, the same thing again to compare without comments
#include <cs50.h>
#include <stdio.h>
int main()
{
double sum = 0.0;
int s = get_int( "how many scores? " );
for(int i = 0; i < s; i++)
sum += get_int( "score: " );
printf("avarage: %lf\n", sum / s );
}
I tried to build a recursion function using pointers that puts the digits with an even index in one pointer and the digits with the odd index to a different one.
For example:
The input 123: 3 has the index of 0 so it will go to *even.
2 has the index of 1 so it will go to *odd.
1 has the index of 2 so it will go to *even.
and in the end *even will have the value of 1+3 = 4 and *odd will have the value of 2.
But I had problems with this function so I tried to do a simplified version of it and It didn't work.
So the simplified version puts the sum of all the digits in *sum:
void main()
{
int num = 25;
int x = 0;
sumDigits(num, &x);
printf("%d", x);
}
void sumDigits(int num, int* sum)
{
if (num >= 0 && num <= 9)
{
*sum = num;
}
else
{
*sum = *sum + num % 10;
sumDigits(num/10, sum);
}
}
But it still won't work properly.
If someone could tell me what's wrong with this function then I could understand how to it and the original one as well.
A simple solution is to handle both an even and an odd digit in each function call.
Like:
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
// Handle even digit
*even += num % 10;
num /= 10;
// Handle odd digit
*odd += num % 10;
num /= 10;
// If there are still digits to be handled
if (num)
{
// Do the recursive call
sumDigits(num, even, odd);
}
}
int main(void)
{
unsigned int num = 123;
unsigned int even = 0, odd = 0;
sumDigits(num, &even, &odd);
printf("even=%d odd=%d", even, odd);
}
That said... this problem is not suitable for recursion a simple loop will be much more efficient.
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
while (num)
{
*even += num % 10;
num /= 10;
*odd += num % 10;
num /= 10;
}
}
For starters the function sumDigits must be declared before main and according to the C Standard the function main without parameters shall be declared like
int main( void )
That is you need to write
#include <stdio.h>
void sumDigits(int num, int* sum);
int main( void )
{
//...
}
There is neither sense to declare the first parameter of the function as having the signed integer type int because it seems the function does not deal with negative numbers.
The first parameter should have the type unsigned long long. In this case you can call the function for an object of any fundamental unsigned integer type.
The function has a logical error. Its last recursive call overwrites the value stored in sum that was calculated in preceding recursive calls of the function due to this if statement
if (num >= 0 && num <= 9)
{
*sum = num;
}
Also pay attention to that the user can pass by reference the second argument that was not initialized. In this case the function will have undefined behavior.
As for your mentioned function that should calculate suns of digits in even and odd positions then it can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void digits_sums( unsigned long long int x, unsigned int *even, unsigned int *odd )
{
const unsigned long long int Base = 10;
x == 0
? ( *even = x, *odd = x )
: ( digits_sums( x / Base / Base, even, odd ), *even += x % Base, *odd += x / Base %Base );
}
int main(void)
{
unsigned int x = 123456789;
unsigned int even;
unsigned int odd;
digits_sums( x, &even, &odd );
printf( "The sum of digits in even positions is %u\n"
"The sum of digits in odd positions is %u\n",
even, odd );
return 0;
}
The program output is
The sum of digits in even positions is 25
The sum of digits in odd positions is 20
Idea is this: http://prntscr.com/m0xopk , It works perfectly except 5, when i give 5 it calculates wrong.I can't understand why?
int i,a,n;
int sum = 1;
scanf("%d",&a);
scanf("%d",&n);
for(i = 1;i <= n;i++){
sum *=pow(a,i);
}
printf("%d",sum);
It works perfectly except 5, when i give 5 it calculates wrong
No, it works perfectly for values less than 5. When you give input 5 for both a and n, the summation resultant number will be 30517578125 which is big for 32 bit int type variable to hold. Instead, you should use uint64_t type variable.
Also, you should not use pow() function for integer type. Check this.
You can do:
#include <stdio.h>
#include <inttypes.h>
int main()
{
int i, a, n;
uint64_t num = 1, result = 1;;
printf ("Enter a: \n");
scanf("%d",&a);
printf ("Enter n: \n");
scanf("%d",&n);
for(i = 0;i < n;i++){
num = num * a;
result = num * result;
}
printf("result: %"PRId64"\n", result);
return 0;
}
Note that this 64 bit solution is also having a limit and will work for input 5 but may not be for a number little bigger than 5. If you want arbitrarily large number, check this.
Integers cant accommodate so large numbers. You need to use float numbers instead.
double calc(double a, int i)
{
double sum = 1;
for(int p = 1; p <= i; p++)
{
sum *= pow(a,i);
}
return sum;
}
I have been struggling with this code and just do not seem to grasp what I am doing wrong.
The code is suppose to calculate : Sum of a series of "Cosine" with pattern [(-1)^i(x)^2i]/(2i)!
Here is my code thus far:
#include <stdio.h>
#include <math.h>
float factorial(int n){
if (n==0)
return 1;
else
return 2*n*factorial(n-1);
}
int main (){
float i, n;
float sum=0;
printf("Enter desired interger: ");
scanf("%f", &n);
for (i=0; i<=1; i++)
sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(n));
printf("The value is %f\n", sum);
return 0;
}
I still working on it, any info or help will be much appreciated!
edit:
Just fixed it guys, this is new format I had to use for my professor:
#include <stdio.h>
#include <math.h>
int factorial(int n)
{
if (n==0) return 1;
else
return n*factorial(n-1);
}
float mycos(float x)
{
float sum=0;
int i;
for (i=0;i<=10;i++) sum = sum + (pow(-1,i)*pow(x,2*i))/factorial(2*i);
return sum;
}
int main()
{
int i=1;
printf(" x mycos(x) cos(x)\n");
for (i=1;i<=10;i++)
printf(" %f %f %f\n", i*.1, mycos(i*.1), cos(i*.1));
return 0;
}
Thank you all for your explanations, they helped out Immensely!
One thing I see, is that your for loop within main only runs through 2 real iterations, once for i == 0, and again for i == 1.
For the taylor expansion to work fairly effectively, it needs to be run through more sequence terms (more loop iterations).
another thing I see, is that your denominator is the n! rather than (2 * n)!
For efficiency, I might also implement the factorial routine as follows:
unsigned int factorial(int n){
unsigned int product = 1;
for(int I = 1; I <= n; I++) product *= I;
return product;
}
The above factorial routine is for a more EXACT factorial calculation, which perhaps you don't need for this purpose. For your purposes, perhaps the floating point variant might be good enough.
float factorial(int n){
float product = 1;
for(int I = 1; I <= n; I++) product *= (float)I;
return product;
}
I should also note why I am stating to perform factorial in this manner. In general a loop construct will be more efficient than its recursive counterpart. Your current implementation is recursive, and thus the implementation I provide SHOULD be quite a bit more efficient from both performance, and memory utilization.
Considering computation expense, you need to stop calculating the series at a point. The more you go, the more precise the result will be, but the more your program spends time. How about this simple program:
#include <stdio.h>
#include <math.h>
#define ITERATIONS 10 //control how far you go
float factorial(int n){
if (n==0)
return 1;
else
return n*factorial(n-1);
}
int main (){
float n;
float sum=0;
printf("Enter desired float: ");
scanf("%f", &n);
int c, i;
for (i=0; i<=ITERATIONS; i++) {
c = (i%2)==0? 1 : -1;
sum = sum + (c*pow(n,2*i+1))/(factorial(2*i+1));
}
printf("The value is %f\n", sum);
return 0;
}
1.) You are only multiplying even no.s in factorial function return 2*n*factorial(n-1); will give only even no.s. Instead you can replace n with 2n here- sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(2n)); This will give the correct (2n!).
2.) Check for the no, of iterations for (i=0; i<=1; i++) this will only run your loop twice. Try more no. of iterations for more accurate anwer.
Why are you calculating power etc for each item in the series? Also need to keep numbers in a suitable range for the data types
i.e. for cos
bool neg_sign = false;
float total = 1.0f;
float current = 1.0f;
for (int i = 0; i < length_of_series; ++i) {
neg_sign = !neg_sign;
current = current * (x / ((2 * i) + 1)) * (x / (( 2 * i) + 2));
total += neg_sign ? -current : current;
}
EDIT
Please see http://codepad.org/swDIh8P5
#include<stdio.h>
# define PRECISION 10 /*the number of terms to be processed*/
main()
{
float x,term=1,s=1.0;
int i,a=2;
scanf("%f",&x);
x=x*x;
for(i=1;i<PRECISION;i++)
{
term=-term*x/(a*(a-1));
s+=term;
a+=2;
}
printf("result=%f",s);
}
Your factorial() function actually calculates 2n.n!, which probably isn't what you had in mind. To calculate (2n)!, you need to remove the 2* from the function body and invoke factorial(2*n).
I am having some problems with writing a C program for this question. Maybe am reading the question wrong and doing it the wrong way. Could someone help me with it please? This is they way I'm trying to do it
#include<stdio.h>
void main(void)
{
int j, sum=0;
long int product=1;
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("\nThe sum of positive odd numbers is: %d", sum);
printf("\nThe product of positive even numbers is: %d", product);
}
The output I am getting is:
The sum of positive odd numbers is: 225
The product of positive even numbers is: -1409286144
I am getting the product part wrong. I have tried using unsigned long int, long long, unsigned long long. Nothing works.
Try using %ld instead of %d in your printf:
printf("\nThe product of positive even numbers is: %ld", product);
Since it's a long int and not an int.
If you use long long int, you'd want %lld. You might need the long long size, given that this is a very very large product. I don't know if your platform's long int is 32 or 64 bit, but you will certainly need a 64 bit number here.
The long long format string can vary depending on your exact platform and compiler, but mostly things have standardized on %lld nowadays. In particular, old Microsoft compilers sometimes used %I64d.
There are no issues as far as the sum of all odd numbers less than 30 is concerned as it's only 225.But the product of all even numbers (or odd numbers for that matter) less than 30 is an enormous number.For that you need a data type with larger capacity.In the following program I have simply used double instead of long int for product and I have used the %e format specifier to display the product in prinf() in a neat way, though you can use %f as well.
#include<stdio.h>
int main(void) //Return type of main() is "int",not "void" as you've used
{
int j, sum=0;
double product=1; //Change type of "product" to "double"
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("The sum of positive odd numbers is: %d\n", sum);
printf("The product of positive even numbers is: %e",product); //Use %e
}
Output
The sum of positive odd numbers is: 225
The product of positive even numbers is: 4.284987e+16
calculate use unsinged int (32bit)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef unsigned short UInt16;
typedef unsigned UInt32;
typedef struct _unums {
size_t size;
UInt16 *nums;//array
} UNums;
void UNums_init(UNums *num, UInt16 n){
num->nums = malloc(sizeof(UInt16));
num->nums[0] = n;
num->size = 1;
}
void UNums_mul(UNums *num, UInt16 n){
UInt16 carry = 0;
size_t i;
for(i=0;i<num->size;++i){
UInt32 wk = n;
wk = wk * num->nums[i] + carry;
num->nums[i] = wk % 10000;
carry = wk / 10000;
}
if(carry){
num->size += 1;
num->nums = realloc(num->nums, num->size * sizeof(UInt16));
num->nums[i] = carry;
}
}
void UNums_print(UNums *num){
size_t i = num->size;
int w = 0;
do{
--i;
printf("%0*hu", w, num->nums[i]);
if(!w) w = 4;
}while(i!=0);
}
void UNum_drop(UNums *num){
free(num->nums);
num->nums = NULL;
}
int main( void ){
UNums n;
UInt16 i;
assert(sizeof(UInt32) == 4);//32bit
assert(sizeof(UInt16) == 2);//16bit
UNums_init(&n, 1);
for(i=2;i<=30;i+=2)
UNums_mul(&n, i);
UNums_print(&n);//42849873690624000
UNum_drop(&n);
return 0;
}