I need to find the remainder of a an average taken from an array so that I can properly round up or down. Basically, if the average of the array has a decimal that is greater than or equal to 0.5, I need to round up, otherwise I need to round down.
long arrayaverage;
long average;
long avremain;
long output;
average = ((array1[0]+array1[1]+array1[2]+array1[3]+array1[4])/5);
avremain=average%long(1.0);
if (avremain>=0.5)
{
output=((average-avremain)+1);
}
else if (avremain<0.5)
{
output=(average-avremain);
}
cout<<"The average of the array is: "<<output<<endl;
There is my code, but the issue I think is with the modulo operator. Whenever I try to run my code, I get the average but it always rounds up. Any help would be much appreciated!
(side note: in an earlier segment of the code, 5 values are collected from the user to form the array, and I know there is no issue with that since an earlier part of the code runs just fine.)
It is not necessary to round up or down, since you're doing all your work with integral types.
long sum = array1[0]+array1[1]+array1[2]+array1[3]+array1[4];
long remainder = sum % 5L; // 5L for consistency working with longs
if (2*remainder > 5L) // this will effectively round up
sum += 5L;
sum -= remainder; // sum will be a multiple of 5 now
average = sum/5L;
All I've done is do the adjustments to the sum before dividing by the number, rather than trying to adjust the average (in which case, rounding is toward zero, and remainder information is lost).
I have assumed that the sum and therefore the average is positive. The adjustment for negatives is trivial, and I'll leave that as an exercise.
BTW: In your code, the expression ..... avremain=average%long(1.0), long(1.0) is equal to 1. Remainder of dividing any positive integer by 1 is always zero, so your approach achieves (literally) nothing.
You have taken everything to long and that is why it is not storing the decimal part. The avremain variable will always give 0 and so, it always show the floor of it.
Use double instead of long;
double arrayaverage;
double average;
double avremain;
double output;
average = ((array1[0]+array1[1]+array1[2]+array1[3]+array1[4])/5);
avremain=average - floor(average);
if (avremain>=0.5)
{
output=((average-avremain)+1);
}
else if (avremain<0.5)
{
output=(average-avremain);
}
cout<<"The average of the array is: "<<output<<endl;
To use floor, write #include <cmath>
Related
int uniquePaths(int m, int n) {
int num = m+n-2;
int den=1;
double ans = 1;
while(den<=m-1) {
ans = ans*(num--)/(den++);
}
cout<<ans;
return (int)ans;
}
The expected answer for m=53, n=4 as input to the above piece of code is 26235 but the code returns 26234. However, the stdout shows 26235.
Could you please help me understand this behavior?
Due to floating-point rounding, your code computes ans to be 26,234.999999999985448084771633148193359375. When it is printed with cout<<ans, the default formatting does not show the full value and rounds it to “26235”. However, when the actual value is converted to int, the result is 26,234.
After setting num to m+n-2, your code is computing num! / ((m-1)!(num-m+1)!), which of course equals num! / ((num-m+1)!(m-1)!). Thus, you can use either m-1 or num-m+1 as the limit. So you can change the while line to these two lines:
int limit = m-1 < num-m+1 ? m-1 : num-m+1;
while(den<=limit) {
and then your code will run to the lower limit, which will avoid dividing ans by factors that are not yet in it. All results will be exact integer results, with no rounding errors, unless you try to calculate a result that exceeds the range of your double format where it is able to represent all integers (up to 253 in the ubiquitous IEEE-754 binary64 format used for double).
Here is my code:
#include <iostream>
#include <cmath>
using namespace std;
int factorial(int);
int main()
{
for(int k = 0; k < 100000; k++)
{
static double sum = 0.0;
double term;
term = (double)pow(-1.0, k) * (double)pow(4.0, 2*k+1) / factorial(2*k+1);
sum = sum + term;
cout << sum << '\n';
}
}
int factorial(int n)
{
if(n == 0)
{
return 1;
}
return n*factorial(n-1);
}
I'm just trying to calculate the value of sine(4) using the maclaurin expansion form of sine. For each console output, the value reads 'nan'. The console gives an error and shuts down after like 10 second. I don't get any errors in the IDE.
There're multiple problems with your approach.
Your factorial function can't return an int. The return value will be way too big, very quickly.
Using pow(-1, value) to get a alternating positive/negative one is very inefficient and will yield incorrect value pretty quick. You should pick 1.0 or -1.0 depending on k's parity.
When you sum a long series of terms, you want to sum the terms with the least magnitude first. Otherwise, you lose precision due to existing bit limiting the range you can reach. In your case, the power of four is dominated by the factorial, so you sum the highest magnitude values first. You'd probably get better precision starting by the other end.
Algorithmically, if you're going to raise 4 to the 2k+1 power and then divide by (2k+1)!, you should keep both the list of factors (4, 4, 4, 4...) and (2,3,4,5,6,7,8,9,....) and simplify both sides. There's plenty of fours to remove on the numerators and denominators at the same time.
Even with those four, I'm not sure you can get anywhere close to the 100000 target you set, without specialized code.
As already stated by others, the intermediate results you will get for large k are magnitudes too large to fit into a double. From a certain k on pow as well as factorial will return infinity. This is simply what happens for very large doubles. And as you then divide one infinity by another you get NaN.
One common trick to deal with too large numbers is using logarithms for intermediate results and only in the end apply the exponential function once.
Some mathematical knowledge of logarithms is required here. To understand what I am doing here you need to know exp(log(x)) == x, log(a^b) == b*log(a), and log(a/b) == log(a) - log(b).
In your case you can rewrite
pow(4, 2*k+1)
to
exp((2*k+1)*log(4))
Then there is still the factorial. The lgamma function can help with factorial(n) == gamma(n+1) and log(factorial(n)) == lgamma(n+1). In short, lgamma gives you the log of a factorial without huge intermediate results.
So summing up, replace
pow(4, 2*k+1) / factorial(2*k+1)
With
exp((2*k+1)*log(4) - lgamma(2*k+2))
This should help you with your NaNs. Also, this should increase performance as lgamma operates in O(1) whereas your factorial is in O(k).
Note, however, that I have still very little confidence that your result will be numerically accurate.
A double has still limited precision of roughly 16 decimal digits. Your 100000 iterations are very likely worthless, probably even harmfull.
The program asks the user for the number of times to flip a coin (n; the number of trials).
A success is considered a heads.
Flawlessly, the program creates a random number between 0 and 1. 0's are considered heads and success.
Then, the program is supposed to output the expected values of getting x amount of heads. For example if the coin was flipped 4 times, what are the following probabilities using the formula
nCk * p^k * (1-p)^(n-k)
Expected 0 heads with n flips: xxx
Expected 1 heads with n flips: xxx
...
Expected n heads with n flips: xxx
When doing this with "larger" numbers, the numbers come out to weird values. It happens if 15 or twenty are put into the input. I have been getting 0's and negative values for the value that should be xxx.
Debugging, I have noticed that the nCk has come out to be negative and not correct towards the upper values and beleive this is the issue. I use this formula for my combination:
double combo = fact(n)/fact(r)/fact(n-r);
here is the psuedocode for my fact function:
long fact(int x)
{
int e; // local counter
factor = 1;
for (e = x; e != 0; e--)
{
factor = factor * e;
}
return factor;
}
Any thoughts? My guess is my factorial or combo functions are exceeding the max values or something.
You haven't mentioned how is factor declared. I think you are getting integer overflows. I suggest you use double. That is because since you are calculating expected values and probabilities, you shouldn't be concerned much about precision.
Try changing your fact function to.
double fact(double x)
{
int e; // local counter
double factor = 1;
for (e = x; e != 0; e--)
{
factor = factor * e;
}
return factor;
}
EDIT:
Also to calculate nCk, you need not calculate factorials 3 times. You can simply calculate this value in the following way.
if k > n/2, k = n-k.
n(n-1)(n-2)...(n-k+1)
nCk = -----------------------
factorial(k)
You're exceeding the maximum value of a long. Factorial grows so quickly that you need the right type of number--what type that is will depend on what values you need.
Long is an signed integer, and as soon as you pass 2^31, the value will become negative (it's using 2's complement math).
Using an unsigned long will buy you a little time (one more bit), but for factorial, it's probably not worth it. If your compiler supports long long, then try an "unsigned long long". That will (usually, depends on compiler and CPU) double the number of bits you're using.
You can also try switching to use double. The problem you'll face there is that you'll lose accuracy as the numbers increase. A double is a floating point number, so you'll have a fixed number of significant digits. If your end result is an approximation, this may work okay, but if you need exact values, it won't work.
If none of these solutions will work for you, you may need to resort to using an "infinite precision" math package, which you should be able to search for. You didn't say if you were using C or C++; this is going to be a lot more pleasant with C++ as it will provide a class that acts like a number and that would use standard arithmetic operators.
I was trying to code an algorithm to count the number of different possible ways the make a certain amount with the given denominations.
Assume the US dollar is available in denominations of $100, $50, $20, $10, $5, $1, $0.25, $0.10, $0.05 and $0.01. Below function, works great for int amount and int denominations
/* Count number of ways of making different combination */
int Count_Num_Ways(double amt, int numDenom, double S[]){
cout << amt << endl; //getchar();
/* combination leads to the amount */
if(amt == 0.00)
return 1;
/* No combination can lead to negative sum*/
if(amt < 0.00)
return 0;
/* All denominations have been exhausted and we have not reached
the required sum */
if(numDenom < 0 && amt >= 0.00)
return 0;
/* either we pick this denomination, this causes a reduction of
picked denomination from the sum for further subproblem, or
we choose to not pick this denomination and
try a different denomination */
return Count_Num_Ways(amt, numDenom - 1, S) +
Count_Num_Ways(amt - S[numDenom], numDenom, S);
}
but when I change my logic from int to float, it goes into infinite loop. I suspect that it is because of floating point comparisons in the code. I am not able to figure out the exact cause for a infinite loop behavior.
Any help in this regard would be helpful.
When dealing with such "small" currency amounts and not dealing with interest it will be much easier to just deal with cents and integer amounts only, not using floating point.
So just change your formula to use cents rather than dollars and keep using integers. Then when you need to display the amounts just divide them by 100 to get the dollars and modulo 100 to get the cents.
floating point operations cannot be exact, because of the finite representation. This way you will never ever end up with exactly 0.0. That's why you always test an interval like so:
if (fabs(amt - 0.0) < TOL)
with a given tolerance of TOL. TOL is chosen appropriately for the application, in this case, 1/2 cent should already be fine.
EDIT: Of course, for this kind of thing, Daemin's answer is much more suitable.
double s_deviation(double data[],int cnt, double mean)
{
int i;
double sum= 0;
double sdeviation;
double x;
//x = mean(billy,a_size);
for(i=0; i<cnt; i++)
{
sum += ((data[i]) - (mean));
}
sdeviation = sqrt(sum/((double)cnt));
return sdeviation;
}
When I cout the result from this function, it gave me NaN.
I tested the value of (mean) and data[i] using
return data[i] and return mean
they are valid.
when i replaced mean with an actual number, the operation returned a finite number.
but with mean as a variable, it produced NaH.
I can't see anything wrong with my code at the moment.
Again, I am sure mean, data are getting the right number based on those tests.
Thank you
I'd guess that the value of mean is large relative to your data, so that some of the ((data[i]) - (mean)) values are negative, and so overall sum ends up being negative.
Then, when you try to compute sqrt(sum/((double)cnt)), you are taking the square root of a negative number, which results in complex number, which is not representable by a double.
However, the underlying problem is that your standard deviation algorithm is incorrect. You are supposed to sum the squares of the distances from the mean, not the distances themselves. Aside from making your computation correct, this also guarantees that sum is never negative, and so you can always get a real-valued square root.
I think You should have
for(i=0; i<cnt; i++)
{
sum += ((data[i]) - (mean)) * ((data[i]) - (mean));
}
In the version You have now sum should be 0, but due to some rounding errors it's most probably a small negative value.
You're taking the sqrt of a negative number (most likely), and that's because you're using the wrong formula for standard deviation.
Standard dev is not the sqrt of the average of (val-mean), it's the sqrt of the average SQUARE of (val-mean).