C++ Cant get to complete the average calculation with double values - c++

What this code does now: I give int values and it calculates the average between them.
What Ive spent hours on trying to get it do: Ive tried making it so that it would calculate the average between double values. Ive tried everything but it always fails or goes into an infinite loop or will not compile.
Question: So how should I modify my code to make it work with double values/numbers?
#include <stdio.h>
void main()
{
int Tau[10]={0,0,0,0,0,0,0,0,0,0};
int r, i = 0;
int m = 0;
int huku = 0;
do{
printf("Enter numbers: ");
scanf_s("%d", &i);
Tau[m]+=i;
huku++;
}while(i != 0);
r = (Tau[m]/(huku-1));
printf("The average of your numbers is; %d\n", r);
}

You have some issues in your code but basically, integer division will not give you doubles. The result of an integer divided by an integer is another integer, not a double. If you want doubles you need to cast either the numerator or denominator to a double and store the result in a double.

Welcome to Numerical Analysis 1001.
Integer math:
2 / 3 = 0;
4 / 2 = 2;
5 / 2 = 2;
Integers don't do fractions.

I don't see why you need Tau to be a vector in your case. An int would suffice.
huku-1 -> That is wrong. It should be just huku.
You need to cast Tau and huku to double when you divide. It won't hurt to check that huku is != 0 also.
m is useless. Just delete it.
r shouldn't be an int if you wish to store Tau/huku in it.
in printf replace %d with %lf

The simplest changes only involve four lines:
double Tau[10] = {0,0,0,0,0,0,0,0,0,0};
double r, i = 0;
scanf_s("%f", &i);
printf("The average of your numbers is; %f\n", r);
Note that this doesn't address the coding issues; all it does is change the code to read and work with double instead of int.

double r = 0;
int i = 0;
r = ((double)Tau[m]/((double)huku-1));
printf("The average of your numbers is; %f\n", r);

// Question is tagged for C++, but the code is in C.
// I will change your code a bit, because you had quite a few mistakes.
#include <stdio.h>
void main ()
{
int sum = 0; // sum of all numbers you entered, to find average you only need total sum and number of entries
int numOfEntries; // number of entries (numbers taken from input)
int inputNum; // variable where you will write numbers from input one by one
double average; // Not really needed, but it can help to simplify the problem to you.
printf("Enter numbers: ");
do
{
scanf_s("%d", &inputNum);
sum += inputNum;
numOfEntries++;
} while (inputNum != 0); // I understand you read numbers until you read value 0.
// int / int will give you rounded number, not the true average, so we need to convert one of the operands to a real number, in this case double
// double / int or int / double will give you a real number as result, which will have true average value, and that is why I converted sum to a real number
if (numOfEntries != 0)
average = (double)sum / numOfEntries;
else
average = 0;
printf("The average of your numbers is; %f\n", average); // Here I did it again - print double instead of int to get true value.
}
It will be even easier to change this:
....
double sum = 0;
...
average = sum / numOfEntries; // Here sum is already double, not int, so you don't need to change it manually.
...
Now, if you want to make it work for double, the only difference will be:
double sum = 0;
double inputNum;
scanf_s("%lf", &inputNum);
average = sum / numOfEntries;
So, to round up the story - you have variable to input a number from keyboard, a variable which holds sum of all entered numbers so far, a variable which counts how many numbers you entered from keyboard. You input numbers until you enter 0 as value, then the program will exit the loop. Formula for average number is sum of all divided by number of numbers. With integers you have to add conversion to a real number or otherways you won't get accurate result.
I hope I didn't confuse you. :D

Related

Euler's number with stop condition

original outdated code:
Write an algorithm that compute the Euler's number until
My professor from Algorithms course gave me the following homework:
Write a C/C++ program that calculates the value of the Euler's number (e) with a given accuracy of eps > 0.
Hint: The number e = 1 + 1/1! +1/2! + ... + 1 / n! + ... = 2.7172 ... can be calculated as the sum of elements of the sequence x_0, x_1, x_2, ..., where x_0 = 1, x_1 = 1+ 1/1 !, x_2 = 1 + 1/1! +1/2 !, ..., the summation continues as long as the condition |x_(i+1) - x_i| >= eps is valid.
As he further explained, eps is the precision of the algorithm. For example, the precision could be 1/100 |x_(i + 1) - x_i| = absolute value of ( x_(i+1) - x_i )
Currently, my program looks in the following way:
#include<iostream>
#include<cstdlib>
#include<math.h>
// Euler's number
using namespace std;
double factorial(double n)
{
double result = 1;
for(double i = 1; i <= n; i++)
{
result = result*i;
}
return result;
}
int main()
{
long double euler = 2;
long double counter = 2;
long double epsilon = 1.0/1000;
long double moduloDifference;
do
{
euler+= 1 / factorial(counter);
counter++;
moduloDifference = (euler + 1 / factorial(counter+1) - euler);
} while(moduloDifference >= epsilon);
printf("%.35Lf ", euler );
return 0;
}
Issues:
It seems my epsilon value does not work properly. It is supposed to control the precision. For example, when I wish precision of 5 digits, I initialize it to 1.0/10000, and it outputs 3 digits before they get truncated after 8 (.7180).
When I use long double data type, and epsilon = 1/10000, my epsilon gets the value 0, and my program runs infinitely. Yet, if change the data type from long double to double, it works. Why epsilon becomes 0 when using long double data type?
How can I optimize the algorithm of finding Euler's number? I know, I can rid off the function and calculate the Euler's value on the fly, but after each attempt to do that, I receive other errors.
One problem with computing Euler's constant this way is pretty simple: you're starting with some fairly large numbers, but since the denominator in each term is N!, the amount added by each successive term shrinks very quickly. Using naive summation, you quickly reach a point where the value you're adding is small enough that it no longer affects the sum.
In the specific case of Euler's constant, since the numbers constantly decrease, one way we can deal with them quite a bit better is to compute and store all the terms, then add them up in reverse order.
Another possibility that's more general is to use Kahan's summation algorithm instead. This keeps track of a running error while it's doing the summation, and takes the current error into account as it's adding each successive term.
For example, I've rewritten your code to use Kahan summation to compute to (approximately) the limit of precision of a typical (80-bit) long double:
#include<iostream>
#include<cstdlib>
#include<math.h>
#include <vector>
#include <iomanip>
#include <limits>
// Euler's number
using namespace std;
long double factorial(long double n)
{
long double result = 1.0L;
for(int i = 1; i <= n; i++)
{
result = result*i;
}
return result;
}
template <class InIt>
typename std::iterator_traits<InIt>::value_type accumulate(InIt begin, InIt end) {
typedef typename std::iterator_traits<InIt>::value_type real;
real sum = real();
real running_error = real();
for ( ; begin != end; ++begin) {
real difference = *begin - running_error;
real temp = sum + difference;
running_error = (temp - sum) - difference;
sum = temp;
}
return sum;
}
int main()
{
std::vector<long double> terms;
long double epsilon = 1e-19;
long double i = 0;
double term;
for (int i=0; (term=1.0L/factorial(i)) >= epsilon; i++)
terms.push_back(term);
int width = std::numeric_limits<long double>::digits10;
std::cout << std::setw(width) << std::setprecision(width) << accumulate(terms.begin(), terms.end()) << "\n";
}
Result: 2.71828182845904522
In fairness, I should actually add that I haven't checked what happens with your code using naive summation--it's possible the problem you're seeing is from some other source. On the other hand, this does fit fairly well with a type of situation where Kahan summation stands at least a reasonable chance of improving results.
#include<iostream>
#include<cmath>
#include<iomanip>
#define EPSILON 1.0/10000000
#define AMOUNT 6
using namespace std;
int main() {
long double e = 2.0, e0;
long double factorial = 1;
int counter = 2;
long double moduloDifference;
do {
e0 = e;
factorial *= counter++;
e += 1.0 / factorial;
moduloDifference = fabs(e - e0);
} while (moduloDifference >= EPSILON);
cout << "Wynik:" << endl;
cout << setprecision(AMOUNT) << e << endl;
return 0;
}
This an optimized version that does not have a separate function to calculate the factorial.
Issue 1: I am still not sure how EPSILON manages the precision.
Issue 2: I do not understand the real difference between long double and double. Regarding my code, why long double requires a decimal point (1.0/someNumber), and double doesn't (1/someNumber)

Problem when i used some large large value i get wrong output with my function

So I'm new to stackoverflow and coding I was learning about functions in c++ and how the stack frame works etc..
in that I made a function for factorials and used that to calculate binomial coefficients. it worked fine for small values like n=10 and r=5 etc... but for large a medium value like 23C12 it gave 4 as answer.
IDK what is wrong with the code or I forgot to add something.
My code:
#include <iostream>
using namespace std;
int fact(int n)
{
int a = 1;
for (int i = 1; i <= n; i++)
{
a *= i;
}
return a;
}
int main()
{
int n, r;
cin >> n >> r;
if (n >= r)
{
int coeff = fact(n) / (fact(n - r) * fact(r));
cout << coeff << endl;
}
else
{
cout << "please enter valid values. i.e n>=r." << endl;
}
return 0;
}
Thanks for your help!
You're not doing anything "wrong" per se. It's just that factorials quicky become huge numbers.
In your example you're using ints, which are typically 32-bit variables. If you take a look at a table of factorials, you'll note that log2(13!) = 32.535.... So the largest factorial that will fit in a 32-bit number is 12!. For a 64-bit variable, the largest factorial you can store is 20! (since log2(21!) = 65.469...).
When you get 4 as the result that's because of overflow.
If you need to be able to calculate such huge numbers, I suggest a bignum library such as GMP.
Factorials overflow easily. In practice you rarely need bare factorials, but they almost always appear in fractions. In your case:
int coeff = fact(n) / (fact(n - r) * fact(r));
Note the the first min(n,n-r,r) factors of the denominator and numerator are identical. I am not going to provide you the code, but I hope an example will help to understand what to do instead.
Consider n=5, r=3 then coeff is
5*4*3*2*1 / 2*1 * 3*2*1
And before actually carrying out any calculations you can reduce that to
5*4 / 2*1
If you are certain that the final result coeff does fit in an int, you can also calculate it using ints. You just need to take care not to overflow the intermediate terms.

Stuck in infinite loop while trying to find nth root of x

double power(double base, int exponent){
//Just for context, a double is larger than a long long int
//Also method programmed to assume non-decimal, non-negative input for root
double answer = base;
if(exponent == 0){
return 1.0;
}
else if(exponent > 0){
for(int i=1; i<exponent; i++){
answer*=base;
}
return answer;
}
else{//if exponent is negative
for(int i=1; i<exponent*(-1); i++){
answer*=base;
}
return 1/answer;
}
}
double newtonRaphsonRoot(double base, int root){//FOR FIDING ROOTS OF CONSTANT #s
if(base == 1){
return 1.0;
}
//Formula: x1 = x0 - f(x0)/f'(x0)
//--------------------------------
//Also method programmed to assume non-negative integer input for root
double epsilon=0.01;//accuracy
double answer = base;//answer starts off as initial guess and becomes better approximated each iteration
if(base > 1){
answer=base/2;
}
while( answer - ( power(answer,root) - base)/(root*power(answer,root-1) ) > epsilon){
//Formula: x1 = x0 - f(x0)/f'(x0). Continue formula until error is less than epsilon
answer = answer - ( power(answer,root) - base)/(root*power(answer,root-1) );
std::cout<<"Approximation: answer = "<< answer <<"\n";
}
return answer;
}
There is a mathematical algorithm for calculating the nth root of a number x, known as the Newton-Raphson method for approximating roots. I tried to program this algorithm. Long story short it seems I'm getting the right answer but
Problem 1: I'm stuck in the while and I don't know why
Problem 2: The accuracy was supposed to be determined by variable epsilon, but answer always comes out to 5 places after decimal.*
One problem is that to check for epsilon the code should be
while (fabs(error) > epsilon) {
... improve ...
}
you are instead checking the next approximation against epsilon (also without fabs).
The other problem is that output stream uses a fixed number of decimals when printing floating point values, if you want to increase that you need to look for std::setprecision (or just use printf("%.18g\n", x); that is what I personally prefer to do).

Rounding a double variable that is supposed to be returned, as opposed to printed [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 7 years ago.
I am writing an average function that takes the average of an array, and returns the answer to 2 decimal places. The only way I found online to do this, however, is by using printf() or cout().
But I do not want it to be printing out each time this function is called because it is used in other functions such as a variance equation and standard deviation equation that shouldn't be displaying the average function.
If anyone could tell me a way to do this, I would be eternally grateful. I think my question is broad enough that code isn't really needed, but here it is anyway just in case. It just continues for quite a few decimal points. Not sure if that's the exact value or a cut off point.
double avg(int a[],int n) // compute the average of n data storing in the array a
{
double addsum = (double)sum(a,n)/(double)n;
return addsum;
}
Since floating point values are always in binary, the best you can do is to return the closest binary number to the decimal that you really desire. But that process is relatively easy.
double round_two_places(double x)
{
return floor(x * 100.0 + 0.5) / 100.0;
}
Use the ceil function from header file math.h in the following way to round off up to two decimal points:
double avg(int a[], int n)
{
double addsum = (double) sum(a, n) / (double) n;
addsum = ceil(x * 100.0 - 0.5) / 100.0;
return addsum;
}
You could shift the value truncate it and shift it back.
Example Code
double round(double value, unsigned n)
{
double shift = std::pow(10, n);
value *= shift;
value = (int) value;
value /= shift;
return value;
}
int main()
{
double value = 1.23456;
std::cout << "before: " << value << ", after: " << round(value, 2) << "\n";
return 0;
}
Caveat: This code may not be sufficient for all use cases (e.g., when round large numbers and/or rounding to many decimal places)
Example Output
before: 1.23456, after: 1.23
std::round gives you the closest integer to its argument. To simulate this rounding of the 3rd digit after the decimal point, use std::round(addsum*100.0)/100.0.
double avg(int a[],int n) // compute the average of n data storing in the array a
{
double addsum = (double)sum(a,n)/(double)n;
return std::round(addsum*100.0)/100.0;
}

Force sum of weights in vector to be 100

I need to populate a vector so that it holds a sum of weights, where the sum must be 100. In other words, the number of items is equal to the divisor, and its values are the quotient, to ensure (force) the sum of the vector to equal 100.
Something like this: 100/3=3.333333...
vector[0]=33.33
vector[1]=33.34
vector[2]=33.33
The sum of this needs to be exactly 100 (some sort of selective rounding?)
Another example: 100/6 = 16.66666667
vector[0]=16.67
vector[1]=16.67
vector[2]=16.66
vector[3]=16.67
vector[4]=16.67
vector[5]=16.66
I've seen something like this done in grocery stores where something on sale might be 3 for $11, so the register displays the prices like 3.67, 3.66, and so on.
The values must add up to exactly 100 though I was thinking of doing this with an epsilon but that wouldn't work.
const int divisor = 6;
const int dividend = 10;
std::vector<double> myVec;
myVec.resize(6);
for (int i = 0; i < divisor; ++i)
{
...some magic that I don't know how to do
}
EDIT: The client wants the values stored (and displayed) in values fixed at two decimal places to visually see they add to 100.
Like the comments say, store money in terms of cents.
#include <vector>
#include <iostream>
#include <iomanip>
std::vector<int> function(int divisor, int total) {
std::vector<int> myVec(divisor);
for (int i = 0; i < divisor; ++i) {
myVec[i] = total/divisor; //rounding down
if (i < total%divisor) //for each leftover
myVec[i] += 1; //add one of the leftovers
}
return myVec;
}
void print_dollars(int cents) {
std::cout << (cents/100) << '.';
std::cout << std::setw(2) << std::setfill('0') << (cents%100) << ' ';
}
int main() {
std::vector<int> r = function(6, 10000);
int sum=0;
for(int i=0; i<r.size(); ++i) {
print_dollars(r[i]);
sum += r[i];
}
std::cout << '\n';
print_dollars(sum);
}
//16.67 16.67 16.67 16.67 16.66 16.66
//100.00
When you divide 100 by 6, you get 16, with 4 leftover. This will put those 4 leftover in each of the first four slots of the vector. Proof of compilation: http://ideone.com/jrInai
There's no one "correct" way to do this. A place to start would be to add up the contents of the vector, and find the difference between 100 and that result you obtained. How you'd fold that in to the individual items would inherently be a heuristic. There are a couple of routes you could take:
Add the difference you found divided by the number of elements in the vector to each element in the vector. This has the advantage that it'll affect an individual value by the smallest amount possible in order to achieve your constraint.
You might want to just add the difference to the first or last element in the vector. This has the advantage that the fewest number of elements in the vector are modified.
You might want to list a separate rounding error element in the vector, which will just be the difference. This gives the most "correct" answer, but might not be what your users want.
Only you can decide what kind of heuristic to use based on the application you're building.
It should be noted that using floating point numbers (e.g. float, double, and long double) may result in errors when storing money values -- you should use fixed point decimal arithmetic for such calculations, because that's how money calculations are done in "the real world". Because floating point uses the base 2 number system internally (on most systems), there will be small rounding errors induced in the conversion from decimal to binary and back. You'll likely have no problem with small values, but if the dollar value is large you'll start seeing problems with the number of digits of precision available in a double.
You can divide into whatever is left as you go, subtracting the last value from the remaining amount.
const int divisor = 6;
const int dividend = 10;
std::vector<double> myVec;
myVec.reserve(6);
double remain = 100.0;
for (int i = divisor; i >= 1; --i)
{
double val = remain / (double)i;
remain -= val;
myVec.push_back(val);
}
In your example,
100/6=16.67 (rounded)
Then you just multiply it by 6-1=5 and get 83.35
And now you know that in order to make the sum to be exactly 100, you need to make the price of the last element to be equal to
100 - 83.35 = 16.65