I am trying to sum a sorted array of positive decreasing floating points. I have seen that the best way to sum them is to start adding up numbers from lowest to highest. I wrote this code to have an example of that, however, the sum that starts on the highest number is more precise. Why? (of course, the sum 1/k^2 should be f=1.644934066848226).
#include <stdio.h>
#include <math.h>
int main() {
double sum = 0;
int n;
int e = 0;
double r = 0;
double f = 1.644934066848226;
double x, y, c, b;
double sum2 = 0;
printf("introduce n\n");
scanf("%d", &n);
double terms[n];
y = 1;
while (e < n) {
x = 1 / ((y) * (y));
terms[e] = x;
sum = sum + x;
y++;
e++;
}
y = y - 1;
e = e - 1;
while (e != -1) {
b = 1 / ((y) * (y));
sum2 = sum2 + b;
e--;
y--;
}
printf("sum from biggest to smallest is %.16f\n", sum);
printf("and its error %.16f\n", f - sum);
printf("sum from smallest to biggest is %.16f\n", sum2);
printf("and its error %.16f\n", f - sum2);
return 0;
}
Your code creates an array double terms[n]; on the stack, and this puts a hard limit on the number of iterations that can be performed before your program crashes.
But you don't even fetch anything from this array, so there's no reason to have it there at all. I altered your code to get rid of terms[]:
#include <stdio.h>
int main() {
double pi2over6 = 1.644934066848226;
double sum = 0.0, sum2 = 0.0;
double y;
int i, n;
printf("Enter number of iterations:\n");
scanf("%d", &n);
y = 1.0;
for (i = 0; i < n; i++) {
sum += 1.0 / (y * y);
y += 1.0;
}
for (i = 0; i < n; i++) {
y -= 1.0;
sum2 += 1.0 / (y * y);
}
printf("sum from biggest to smallest is %.16f\n", sum);
printf("and its error %.16f\n", pi2over6 - sum);
printf("sum from smallest to biggest is %.16f\n", sum2);
printf("and its error %.16f\n", pi2over6 - sum2);
return 0;
}
When this is run with, say, a billion iterations, the smallest-first approach is considerably more accurate:
Enter number of iterations:
1000000000
sum from biggest to smallest is 1.6449340578345750
and its error 0.0000000090136509
sum from smallest to biggest is 1.6449340658482263
and its error 0.0000000009999996
When you add two floating-point numbers with different orders of magnitude, the lower order bits of the smallest number are lost.
When you sum from smallest to largest, the partial sums grow like Σ1/k² for k from N to n, i.e. approximately 1/n-1/N (in blue), to be compared to 1/n².
When you sum from largest to smallest, the partial sums grow like Σ1/k² for k from n to N, which is about π²/6-1/n (in green) to be compared to 1/n².
It is clear that the second case results in many more bit losses.
Related
I want to calculate pi but I am getting 3.058403 as a result. How can I fix this code?
#include <stdio.h>
int main(){
double x = 0;
float g =0;
printf("How many terms to calculate pi to? ");
scanf("%f", &g);
int n;
for (n = 0; n < g ; n++){
double z = 1.0 / (2 * n + 1);
if ((n % 2) == 1){
z = z * -1;
}
x = (x + z);
}
double p = 4 * x;
printf("The value of pi is: %f", p);
return 0;
}
This is not really an answer because the actual answer has been discussed in the comment section.
Corrected version of your code:
removed pointless parentheses
use meaningful variable names
use of int for integer comparison
declaration of variables as close as possible to their scope
code formatted properly
#include <stdio.h>
int main() {
printf("How many terms to calculate pi to? ");
int nbofterms;
scanf("%d", &nbofterms);
double x = 0;
for (int n = 0; n < nbofterms; n++) {
double z = 1.0 / (2 * n + 1);
if (n % 2 == 1) {
z *= -1;
}
x = (x + z);
}
double pi = 4 * x;
printf("The value of pi is: %f", pi);
return 0;
}
In the code shown below, what does average /= 5.0 mean? What is it implying? This is for C language. I am using this code to find out the average marks obtained in 2 subjects denoted as i and j.
#include <stdio.h>
int main()
{
int grades[2][5];
float average;
int i;
int j;
grades[0][0]=98;
grades[0][1]=98;
grades[0][2]=98;
grades[0][3]=88;
grades[0][4]=98;
grades[1][0]=98;
grades[1][1]=98;
grades[1][2]=98;
grades[1][3]=98;
grades[1][4]=98;
for (i = 0; i < 2; i ++)
{
average = 0;
for (j = 0; j < 5; j ++)
{
average += grades[i][j];
}
average /= 5.0;
printf("The average of subject %d is: %.2f\n", i, average);
}
}
This is a shortcut for average = average / 5.0;.
You can do the same for many operations:
average += 5.0; is the same as average = average + 5.0;
average -= 5.0; is the same as average = average - 5.0;
average *= 5.0; is the same as average = average * 5.0;
These are called compound assignment operators.
printf("Sum Digit Program\n");
int n,re, sum = 0;
printf("Enter an integer n="); scanf("%d", &n);
while(n){
re = n % 10;
sum = sum + re;
n = n / 10;
}
printf("Sum digit = %d", sum);
return 0;
}
I try this and it works well with positive integer but when I enter a negative integer like: -323 => -8
It's supposed to be -3+2+3 =2 not -3-2-3=-8
I try using abs function but it still doesn't work right
OP almost had it. Simply treat MSDigit as signed. All other digits, use abs(rem). Works for INT_MIN
printf("Sum Digit Program\n");
int sum = 0;
printf("Enter an integer n=");
scanf("%d", &n);
while (n) {
int re = n % 10;
n = n / 10;
sum += n ? abs(re) : re; // At MSDigit when n==0
}
printf("Sum digit = %d", sum);
Well, you may use conditional operator to store the sign value like int sign = (n >= 0 ? 1 : -1); as shown below -
#include <stdio.h>
#include <stdlib.h>
/*
* #brief Logic for returning sum of digits
*/
int digi_sum(int n)
{
int sign = (n >= 0 ? 1 : -1);
int sum = 0;
n *= sign;
while (n)
{
if (n < 10)
sum += (sign * (n % 10));
else
sum += n % 10;
n /= 10;
printf("Sum: %d, n: %d\n", sum, n);
}
printf("sum: %d, n: %d\n", sum, n);
return sum;
}
/*
* #brief Driver function
*/
int main(int argc, char *argv[])
{
int num = -323;
printf("Sum: %d\n", digi_sum(num));
return 0;
}
The idea is to store the sign of the number into a separate variable and use it when n < 10.
Use n=abs(n/10) instead of n=n/10
#include <stdio.h>
#include <math.h>
main()
{
printf("Sum Digit Program\n");
int n,re, sum = 0;
printf("Enter an integer n="); scanf("%d", &n);
while(n)
{
re = n % 10;
sum = sum + re;
n =abs(n/10);
}
printf("Sum digit = %d", sum);
return 0;
}
You can add a condition to the first line of your loop to make sure that the sum so far is positive when n < 10, after that it will make the subtraction for the least digit if it has too. Then your loop should look like this:
while(n){
if (abs(n) < 10) {
sum = abs(sum);
}
re = n % 10;
sum = sum + re;
n = n / 10;
}
I think that you need a precondition for the first number.
with an if then else.
Solved
I changed the output to see the values
include<stdio.h>
int main(void)
{
int re,n;
int sum =0 ;
printf("Sum Digit Program \n");
printf("Enter an integer n= ");
scanf("%d", &n);
while(n)
{
if (abs(n) < 10) {
sum = abs(sum);
}
re= (n % 10);
sum = sum + re;
n= n / 10;
printf ("\n re = %d , n= %d \n", re, n);
}
printf ("\n sum= %d \n",sum);
return 0;
}
I wrote the code for the following program but I don't understand how I can involve a function. The question asks me to use a function that returns the sum of divisors. Please take a look at the question and my code and try to help me out.
THE QUESTION:
Write a C program that finds and prints the sum of divisors for all
the numbers between 101 and 110. The divisors of x are those numbers
x divides without a remainder (e.g. the divisors of number 10 are 1,
2, 5, and 10 and their sum = 1+2+5+10=18, the divisors of number 11
are 1 and 11 and their sum=1+11=12, and so forth).
Your program should also print the number (101 to 110) that has the maximum sum of divisors.
Your program should use at least one function called div_sum that
takes a number and returns its sum of divisors.
MY CODE:
#include <iostream>
#include <stdio.h>
int main()
{
int i=1, x=101, sum, smax=0, xmax=0;
for (x=101; x<=110; x++)
{ sum=0;
for(i=1; i<=x; i++)
{
if(x%i==0)
sum+=i;
}
if(sum>smax)
{
smax=sum;
xmax=x;
}
printf("The sum of factors of %d = %d\n",x,sum);
}
printf("The number that has the maximum sum of divisors is %d with the sum of %d",xmax,smax);
return 0;
}
You can move the loop where you calculate sum of divisors for each x to separate function:
int div_sum(int x) {
int sum = 0;
for(int i=1; i<=x; i++)
{
if(x%i==0)
sum+=i;
}
return sum;
}
and use it in your program:
for (x=101; x<=110; x++)
{
sum= div_sum(x);
if(sum > amax)
...
}
For each number in the loop, call the function. The function should have all the code you currently have in the loop.
Your code is actually really close.
Here's what I did:
void div_sum()
{
int sum;
int max_sum = 0;
int max_num;
for (int x = 101; x <= 110; x++)
{
sum = 0;
for (int i = 1; i <= x; i++)
if (x%i == 0)
sum = sum + i;
printf("\nFor the number %d, the sum of the divisors is %d\n", x, sum);
if (sum > max_sum)
{
max_sum = sum;
max_num = x;
}
}
printf("max = %d\n", max_num);
}
good day, I am making a program that is using the e function:
e(n) = 1 + (1/1!) + (1/2!)+ ... + (1/n!)
with this function of C:
double e(double x, double x2){
double sum, kf;
int i, m, n;
// printf("Please input the number of x: ");
// scanf("%lf", &x);
sum = 0.0;
for (i=1; i<=x; i++){
kf=1.0;
for (m=1; m<=i; m++) {
kf*=1.0/m;
}
sum+=kf;
}
return printf("e=%lf\n", 1+sum);
}
well, it was the e function. now, I want to find the minimum number n that makes:
|e(n) - e(n+1)| < x
(absolute value of e(n) - e(n+1) is smaller than x
where x is a long float that users input, will be 0.1, 0.001, 0.0001,...
Any answers are highly appreciated.
Using algebra and the e function definition, |e(n) - e(n+1)| < x can be simplified to (1/n!) < x, which can be expanded to (1/1) * (1/2) * (1/3) * ... * (1/n) < x.
int minN(double x) {
double sum = 1;
int n;
for(n = 0; sum >= x; n++) {
sum *= 1/(n+1);
}
return n;
}