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 );
}
Related
I am new to C and stack overflow so i'm not really sure where to ask the question. I have to make code for population growth. X is the starting population and Y is the end population. I have to calculate time (T). Every year there are X/3 newborns and X/4 deaths. The formula I am using is log(base: 1+(X/12)/100)(Y/X). To test I use 100 as starting population and 200 as the end population. The years are 8.66 which is rounded up to 9 years. I tried changing the variable type but i'm not sure which type I should use. The code is below. Thanks in advance.<
#include <cs50.h>
#include <stdio.h>
#include <math.h>
double log_a_to_base_b( double a, double b)
{
return log(a) / log(b);
}
int main(void)
{
// Prompt for start size
int X;
do
{
X = get_int ("How many llamas do you start with? \n" );
}
while (X < 1);
// Prompt for end size
int Y;
do
{
Y = get_int ("How many llamas do you have after a certain period of time? \n" );
}
while (Y < 1 || Y < X);
// Calculate number of years until we reach threshold
double a = Y/X;
double b = 1+(X/1200);
{
printf("Start size : %i \n", X );
printf("End size : %i \n", Y);
printf("Years:%f \n", log_a_to_base_b(a, b));
}
return 0;
}
I tried the following,
unsigned int log_a_to_base_b( unsigned int a,unsigned int b)
{
return log(a) / log(b);
}
int main(void)
{
printf("%u\n", log_a_to_base_b(10,2)); // Yields 3
return 0;
}
It always returns the correct answer in integer. You will have to change the %f in your printf. I think that rest of the program runs fine. But you still need to understand that all of the divisions in main are being done on integers. So they will not get you precise results (e.g 3/2=1.000). And you are also returning unsigned int, so that will always give highest integer smaller than the log.
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;
}
I tried to solve a task on codewars and happened something strange, in one case casting worked as usual and in the second o got strange behavior. Here is the code:
#include <stdio.h>
#include <string.h>
#include <math.h>
int digital_root(int n) {
char tmp[30];
char *ptr;
while(n > 9){
sprintf(tmp, "%d", n);
int len = strlen(tmp);
float n_tmp = n / (pow(10, len));
n = 0;
for(int i = 1; i <=len; i++){
float t = n_tmp * (pow(10, i));
printf(" vars = [%f , %d] ", t, (int)t); //this line
n += (int) t;
n_tmp -= (int)t/pow(10,i);
}
}
return n;
}
int main()
{
digital_root(16);
return 0;
}
And the line printf(" vars = [%f , %d] ", t, (int)t); outputs: vars = [1.600000 , 1] vars = [6.000000 , 5], what is so strange. Can someone explain this behavior?
Every casting float to int is a rounding, so every time you do it, stop for a second and think: what kind of rounding do I need this time? Dropping the fractional part? floor()? ceil()? Or rounding positive float towards nearest int? If 5.999999999999 should be 6, use (int)(t+.5), not (int)t.
Or you can mimic the printf behavior and round only the smallest float fraction, which can vary (depending on the biggest value you use). (int)(t+.000001) will round both 1.9 to 1 (as it probably should), and 3.9999999999 to 4 (because it is 4 with some tiny number representation errors).
You should however know the size of a fraction which can be an actual, meaningful part of your data. Everything smaller than this fraction must be rounded. It can be either .00000001 or .5, that depends on your needs and the algorithm itself.
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 want to convert the fractional part of a double value with precision upto 4 digits into integer. but when i do it, i lose precision. Is there any way so that i can get the precise value?
#include<stdio.h>
int main()
{
double number;
double fractional_part;
int output;
number = 1.1234;
fractional_part = number-(int)number;
fractional_part = fractional_part*10000.0;
printf("%lf\n",fractional_part);
output = (int)fractional_part;
printf("%d\n",output);
return 0;
}
i am expecting output to be 1234 but it gives 1233. please suggest a way so that i can get desired output. i want the solution in C language.
Assuming you want to get back a positive fraction even for negative values, I'd go with
(int)round(fabs(value - trunc(value)) * 1e4)
which should give you the expected result 1234.
If you do not round and just truncate the value
(int)(fabs(value - trunc(value)) * 1e4)
(which is essentially the same as your original code), you'll end up with the unexpected result 1233 as 1.1234 - 1.0 = 0.12339999999999995 in double precision.
Without using round(), you'll also get the expected result if you change the order of operations to
(int)(fabs(value * 1e4 - trunc(value) * 1e4))
If the integral part of value is large enough, floating-point inaccuracies will of course kick in again.
You can also use modf() instead of trunc() as David suggests, which is probably the best approach as far as floating point accuracy goes:
double dummy;
(int)round(fabs(modf(value, &dummy)) * 1e4)
number= 1.1234, whole=1, fraction=1234
int main()
{
double number;
int whole, fraction;
number = 1.1234;
whole= (int)number;
fraction =(int)(number*10000);
fraction = fraction-(whole *10000);
printf("%d\n",fraction);
printf("%d\n",whole);
return 0;
}
A solution for any number could be:
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
float number = 123.46244;
float number_final;
float temp = number; // keep the number in a temporary variable
int temp2 = 1; // keep the length of the fractional part
while (fmod(temp, 10) !=0) // find the length of the fractional part
{
temp = temp*10;
temp2 *= 10;
}
temp /= 10; // in tins step our number is lile this xxxx0
temp2 /= 10;
number_final = fmod(temp, temp2);
cout<<number_final;
getch();
return 0;
}
Use modf and ceil
#include <stdio.h>
#include <math.h>
int main(void)
{
double param, fractpart, intpart;
int output;
param = 1.1234;
fractpart = modf(param , &intpart);
output = (int)(ceil(fractpart * 10000));
printf("%d\n", output);
return 0;
}