Here i want to count the total numbers of rectangles in M*N grid. This code is working properly but not for the large input like M=100000 N=100000. It shows something like -nan or any negative integer.
Thee result will be the modulo of 1000000007. How can i get an accurate answer with this large integer range?
Thank you
#include<iostream>
#include<cmath>
using namespace std;
double factorial(int);
int main(){
int m,n;
double mod= 1000000007;
double p,q,result;
cout << "\nPlease enter the dimensions of grid: ";
cin>>m>>n;
if (m <0&&n<0)
{
cout << "Invalid dimensions!\n";
return 1;
}
m++; n++; /*if n is the no of vertical/horizontal boxes,
there will be n+1 vertical/horizontal lines in the grid */
result=(factorial(m)/(2*factorial(m-2)))*(factorial(n)/(2*factorial(n-2)));
cout<<"\nThe rectangles in the grid is:"<<fmod(result,mod);
return 0;
}
double factorial(int x) {
double temp;
if(x <= 1) return 1;
temp = x * factorial(x - 1);
return temp;
}
You can't do 100000 factorial in a double-precision number, you'll get overflow (as you've observed).
In your case think about this expansion of what you're calculating
m * (m-1) * (m-2) * (m-3) * ... * 2 * 1
-----------------------------------------
2 * (m-2) * (m-3) * ... * 2 * 1
This all simplifies to m * (m-1) / 2. So, you don't need your factorial function at all.
Edit: The code in another post was not right. Try this:
result = static_cast<double>(m) * (m-1) * n * (n-1) / 4;
Not really programming related, but factorial(m)/(2*factorial(m-2) is the same as m * (m-1) / 2 which will probably not cause an overflow.
#include<iostream>
#include<cmath>
using namespace std;
double factorial(int);
int main(){
int m,n;
double mod= 1000000007;
double p,q,result;
cout << "\nPlease enter the dimensions of grid: ";
cin>>m>>n;
if (m <0&&n<0)
{
cout << "Invalid dimensions!\n";
return 1;
}
m++; n++; /*if n is the no of vertical/horizontal boxes,
there will be n+1 vertical/horizontal lines in the grid */
//This is where I had the typo. Forgot to divide by 2.
result=((m*(m-1))/2)*((n*(n-1))/2);
cout<<"\nThe rectangles in the grid is:"<<fmod(result,mod);
return 0;
}
/*double factorial(int x) {
double temp;
if(x <= 1) return 1;
temp = x * factorial(x - 1);
return temp;
} */
This should work fine. There was no need for you to implement a factorial function. You can have just simplified your statement down and you would have gotten your answer.
Related
hey I am making small C++ program to calculate the value of sin(x) till 7 decimal points but when I calculate sin(PI/2) using this program it gives me 0.9999997 rather than 1.0000000 how can I solve this error?
I know of little bit why I'm getting this value as output, question is what should be my approach to solve this logical error?
here is my code for reference
#include <iostream>
#include <iomanip>
#define PI 3.1415926535897932384626433832795
using namespace std;
double sin(double x);
int factorial(int n);
double Pow(double a, int b);
int main()
{
double x = PI / 2;
cout << setprecision(7)<< sin(x);
return 0;
}
double sin(double x)
{
int n = 1; //counter for odd powers.
double Sum = 0; // to store every individual expression.
double t = 1; // temp variable to store individual expression
for ( n = 1; t > 10e-7; Sum += t, n = n + 2)
{
// here i have calculated two terms at a time because addition of two consecutive terms is always less than 1.
t = (Pow(-1.00, n + 1) * Pow(x, (2 * n) - 1) / factorial((2 * n) - 1))
+
(Pow(-1.00, n + 2) * Pow(x, (2 * (n+1)) - 1) / factorial((2 * (n+1)) - 1));
}
return Sum;
}
int factorial(int n)
{
if (n < 2)
{
return 1;
}
else
{
return n * factorial(n - 1);
}
}
double Pow(double a, int b)
{
if (b == 1)
{
return a;
}
else
{
return a * Pow(a, b - 1);
}
}
sin(PI/2) ... it gives me 0.9999997 rather than 1.0000000
For values outside [-pi/4...+pi/4] the Taylor's sin/cos series converges slowly and suffers from cancelations of terms and overflow of int factorial(int n)**. Stay in the sweet range.
Consider using trig properties sin(x + pi/2) = cos(x), sin(x + pi) = -sin(x), etc. to bring x in to the [-pi/4...+pi/4] range.
Code uses remquo (ref2) to find the remainder and part of quotient.
// Bring x into the -pi/4 ... pi/4 range (i.e. +/- 45 degrees)
// and then call owns own sin/cos function.
double my_wide_range_sin(double x) {
if (x < 0.0) {
return -my_sin(-x);
}
int quo;
double x90 = remquo(fabs(x), pi/2, &quo);
switch (quo % 4) {
case 0:
return sin_sweet_range(x90);
case 1:
return cos_sweet_range(x90);
case 2:
return sin_sweet_range(-x90);
case 3:
return -cos_sweet_range(x90);
}
return 0.0;
}
This implies OP needs to code up a cos() function too.
** Could use long long instead of int to marginally extend the useful range of int factorial(int n) but that only adds a few x. Could use double.
A better approach would not use factorial() at all, but scale each successive term by 1.0/(n * (n+1)) or the like.
I see three bugs:
10e-7 is 10*10^(-7) which seems to be 10 times larger than you want. I think you wanted 1e-7.
Your test t > 10e-7 will become false, and exit the loop, if t is still large but negative. You may want abs(t) > 1e-7.
To get the desired accuracy, you need to get up to n = 7, which has you computing factorial(13), which overflows a 32-bit int. (If using gcc you can catch this with -fsanitize=undefined or -ftrapv.) You can gain some breathing room by using long long int which is at least 64 bits, or int64_t.
I'm working on a code that calculates PI with n terms. However, my code only works correctly with some values of n.
This piece of code even numbers do not work and when I switch up the negative sign the odd numbers do not work.
double PI(int n, double y=2){
double sum = 0;
if (n==0){
return 3;
}else if (n % 2 != 0){
sum = (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;
}else{
sum= -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2) ;
}
return sum;
}
int main(int argc, const char * argv[]) {
double n = PI (2,2);
cout << n << endl;
}
For n = 2 I expected a result of 3.1333 but I got a value of 2.86667
This is the formula for calculating PI , y is the denominator and n is the number of terms
Firstly, I will assume that a complete runnable case of your code looks like
#include <iostream>
using namespace std;
double PI(int n, double y=2){
double sum = 0;
if (n==0){
return 3;
}else if (n % 2 != 0){
sum = (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;
}else{
sum= -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2) ;
}
return sum;
}
int main(int argc, const char * argv[]) {
double n = PI (2,2);
cout << n << endl;
}
I believe that you are attempting to compute pi through the formula
(pi - 3)/4 = \sum_{k = 1}^{\infty} (-1)^{k+1} / ((2k(2k+1)(2k+2)),
(where here and elsewhere I use LaTeX code to represent mathy things). This is a good formula that converges pretty quickly despite being so simple. If you were to use the first two terms of the sum, you would find that
(pi - 3)/4 \approx 1/(2*3*4) - 1/(4*5*6) ==> pi \approx 3.13333,
which you seem to indicate in your question.
To see what's wrong, you might trace through your first function call with PI(2, 2). This produces three terms.
n=2: 2 % 2 == 0, so the first term is -4/(2*3*4) + PI(1, 4). This is the wrong sign.
n=1: 1 % 2 == 1, so the second term is 4/(4*5*6), which is also the wrong sign.
n=0: n == 0, so the third term is 3, which is the correct sign.
So you have computed
3 - 4/(2*3*4) + 4/(4*5*6)
and we can see that there are many sign errors.
The underlying reason is because you are determining the sign based on n, but if you examine the formula the sign depends on y. Or in particular, it depends on whether y/2 is odd or even (in your formulation, where you are apparently only going to provide even y values to your sum).
You should change y and n appropriately. Or you might recognize that there is no reason to decouple them, and use something like the following code. In this code, n represents the number of terms to use and we compute y accordingly.
#include <iostream>
using namespace std;
double updatedPI(int n)
{
int y = 2*n;
if (n == 0) { return 3; }
else if (n % 2 == 1)
{
return 4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
}
else
{
return -4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
}
}
int main() {
double n = updatedPI(3);
cout << n << endl;
}
The only problem with your code is that y is calculated incorrectly. It has to be equal to 2 * n. Simply modifying your code that way gives correct results:
Live demo: https://wandbox.org/permlink/3pZNYZYbtHm7k1ND
That is, get rid of the y function parameter and set int y = 2 * n; in your function.
I was given a task to write a program that displays:
I coded this:
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
int a, n = 1, f = 1;
float s = 0;
cin >> a;
while(n <= a)
{
f = f * n;
s += 1 / (float)f;
n = n + 1;
}
cout << s;
getch();
}
So this displays -
s = 1 + 1/2! + 1/3! + 1/4! .... + 1/a!, including odd and even factorials.
For the past two hours I am trying to figure out how can I modify this code so that it displays the desired result. But I couldn't figure it out yet.
Question:
What changes should I make to my code?
You need to accumulate the sum while checking the counter n and only calculate the even factorials:
int n;
double sum = 1;
cin >> n;
for(int i = 2; i < n; ++i{
if(i % 2 == 0) sum += 1 / factorial(i);
}
In your code:
while(n <= a)
{
f = f * n;
// checks if n is even;
// n even if the remainder of the division by 2 is zero
if(n % 2 == 0){
s += 1 / (float)f;
}
n = n + 1;
}
12! is the largest value that fits in an 32 bit integer. You should use double for all the numbers. For even factorials, starting with f = 1 (0!), f = f * (n-1) * n, where n = 2, 4, 6, 8, ... .
You have almost everything you need in place (assuming you don't want to make design changes based on the issues brought up in the comments).
All you need to change is what you multiply f by in each step. To build up n! you are multiplying by n in each step. To build up (2n)! you would multiply by 2*n*(2*n-1)
Edit: Your second theory about what the instructor wants would need only slightly more of a change. Your inner loop could be replaced by
while(n < a)
{
f = f * n * (n+1);
s += 1 / f;
n = n + 2;
}
Edit2: To run your program I made several changes for I/O things you did that don't work in my copy of GCC. Hopefully those won't distract from the main point of the following code. I also added a second, more complicated and more accurate method of computing the answer to see how much was lost in floating point rounding.
So this code computes the answer twice, once by the method I suggested you change your code to and once by a more accurate method (using double instead of float and adding the numbers in the more accurate sequence via a recursive function). Then it display your answer and the difference between the two answers.
Running that shows the version I suggested gets all the displayed digits correct and is only wrong for the values of a I tried by tiny amounts that would need more display precision to notice:
#include<iostream>
using namespace std;
double fac_sum(int n, int a, double f)
{
if ( n > a )
return 0;
f *= n * (n-1);
return fac_sum(n+2, a, f) + 1 / f;
}
int main()
{
int a, n = 1;
float f = 1;
float s = 0;
cin >> a;
while(n < a)
{
f = f * n * (n+1);
s += 1 / f;
n = n + 2;
}
cout << s;
cout << " approx error was " << fac_sum( 2, a, 1.0)-s;
return 0;
}
For 8 that displays 0.54308 approx error was -3.23568e-08
I hope you understand the e-08 notation meaning the error is in the 8'th digit to the right of the .
Edit3: I changed f to float in this post because I had copied/tested thinking f was float, so parts of my answer didn't make sense when f was int
I was finding out the algorithm for finding out the square root without using sqrt function and then tried to put into programming. I end up with this working code in C++
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the number\n";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
return 0;
}
Now the problem is initializing the number of iterations nCount in the declaratione ( here it is 50). For example to find out square root of 36 it takes 22 iterations, so no problem whereas finding the square root of 15625 takes more than 50 iterations, So it would return the value of temp after 50 iterations. Please give a solution for this.
There is a better algorithm, which needs at most 6 iterations to converge to maximum precision for double numbers:
#include <math.h>
double sqrt(double x) {
if (x <= 0)
return 0; // if negative number throw an exception?
int exp = 0;
x = frexp(x, &exp); // extract binary exponent from x
if (exp & 1) { // we want exponent to be even
exp--;
x *= 2;
}
double y = (1+x)/2; // first approximation
double z = 0;
while (y != z) { // yes, we CAN compare doubles here!
z = y;
y = (y + x/y) / 2;
}
return ldexp(y, exp/2); // multiply answer by 2^(exp/2)
}
Algorithm starts with 1 as first approximation for square root value.
Then, on each step, it improves next approximation by taking average between current value y and x/y. If y = sqrt(x), it will be the same. If y > sqrt(x), then x/y < sqrt(x) by about the same amount. In other words, it will converge very fast.
UPDATE: To speed up convergence on very large or very small numbers, changed sqrt() function to extract binary exponent and compute square root from number in [1, 4) range. It now needs frexp() from <math.h> to get binary exponent, but it is possible to get this exponent by extracting bits from IEEE-754 number format without using frexp().
Why not try to use the Babylonian method for finding a square root.
Here is my code for it:
double sqrt(double number)
{
double error = 0.00001; //define the precision of your result
double s = number;
while ((s - number / s) > error) //loop until precision satisfied
{
s = (s + number / s) / 2;
}
return s;
}
Good luck!
Remove your nCount altogether (as there are some roots that this algorithm will take many iterations for).
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0;
while(fabs(num - (temp * temp)) > SOME_SMALL_VALUE)
{
temp = (lower_bound+upper_bound)/2;
if (temp*temp >= num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
}
return temp;
}
As I found this question is old and have many answers but I have an answer which is simple and working great..
#define EPSILON 0.0000001 // least minimum value for comparison
double SquareRoot(double _val) {
double low = 0;
double high = _val;
double mid = 0;
while (high - low > EPSILON) {
mid = low + (high - low) / 2; // finding mid value
if (mid*mid > _val) {
high = mid;
} else {
low = mid;
}
}
return mid;
}
I hope it will be helpful for future users.
if you need to find square root without using sqrt(),use root=pow(x,0.5).
Where x is value whose square root you need to find.
//long division method.
#include<iostream>
using namespace std;
int main() {
int n, i = 1, divisor, dividend, j = 1, digit;
cin >> n;
while (i * i < n) {
i = i + 1;
}
i = i - 1;
cout << i << '.';
divisor = 2 * i;
dividend = n - (i * i );
while( j <= 5) {
dividend = dividend * 100;
digit = 0;
while ((divisor * 10 + digit) * digit < dividend) {
digit = digit + 1;
}
digit = digit - 1;
cout << digit;
dividend = dividend - ((divisor * 10 + digit) * digit);
divisor = divisor * 10 + 2*digit;
j = j + 1;
}
cout << endl;
return 0;
}
Here is a very simple but unsafe approach to find the square-root of a number.
Unsafe because it only works by natural numbers, where you know that the base respectively the exponent are natural numbers. I had to use it for a task where i was neither allowed to use the #include<cmath> -library, nor i was allowed to use pointers.
potency = base ^ exponent
// FUNCTION: square-root
int sqrt(int x)
{
int quotient = 0;
int i = 0;
bool resultfound = false;
while (resultfound == false) {
if (i*i == x) {
quotient = i;
resultfound = true;
}
i++;
}
return quotient;
}
This a very simple recursive approach.
double mySqrt(double v, double test) {
if (abs(test * test - v) < 0.0001) {
return test;
}
double highOrLow = v / test;
return mySqrt(v, (test + highOrLow) / 2.0);
}
double mySqrt(double v) {
return mySqrt(v, v/2.0);
}
Here is a very awesome code to find sqrt and even faster than original sqrt function.
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f375a86 - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x=1/x;
return x;
}
After looking at the previous responses, I hope this will help resolve any ambiguities. In case the similarities in the previous solutions and my solution are illusive, or this method of solving for roots is unclear, I've also made a graph which can be found here.
This is a working root function capable of solving for any nth-root
(default is square root for the sake of this question)
#include <cmath>
// for "pow" function
double sqrt(double A, double root = 2) {
const double e = 2.71828182846;
return pow(e,(pow(10.0,9.0)/root)*(1.0-(pow(A,-pow(10.0,-9.0)))));
}
Explanation:
click here for graph
This works via Taylor series, logarithmic properties, and a bit of algebra.
Take, for example:
log A = N
x
*Note: for square-root, N = 2; for any other root you only need to change the one variable, N.
1) Change the base, convert the base 'x' log function to natural log,
log A => ln(A)/ln(x) = N
x
2) Rearrange to isolate ln(x), and eventually just 'x',
ln(A)/N = ln(x)
3) Set both sides as exponents of 'e',
e^(ln(A)/N) = e^(ln(x)) >~{ e^ln(x) == x }~> e^(ln(A)/N) = x
4) Taylor series represents "ln" as an infinite series,
ln(x) = (k=1)Sigma: (1/k)(-1^(k+1))(k-1)^n
<~~~ expanded ~~~>
[(x-1)] - [(1/2)(x-1)^2] + [(1/3)(x-1)^3] - [(1/4)(x-1)^4] + . . .
*Note: Continue the series for increased accuracy. For brevity, 10^9 is used in my function which expresses the series convergence for the natural log with about 7 digits, or the 10-millionths place, for precision,
ln(x) = 10^9(1-x^(-10^(-9)))
5) Now, just plug in this equation for natural log into the simplified equation obtained in step 3.
e^[((10^9)/N)(1-A^(-10^-9)] = nth-root of (A)
6) This implementation might seem like overkill; however, its purpose is to demonstrate how you can solve for roots without having to guess and check. Also, it would enable you to replace the pow function from the cmath library with your own pow function:
double power(double base, double exponent) {
if (exponent == 0) return 1;
int wholeInt = (int)exponent;
double decimal = exponent - (double)wholeInt;
if (decimal) {
int powerInv = 1/decimal;
if (!wholeInt) return root(base,powerInv);
else return power(root(base,powerInv),wholeInt,true);
}
return power(base, exponent, true);
}
double power(double base, int exponent, bool flag) {
if (exponent < 0) return 1/power(base,-exponent,true);
if (exponent > 0) return base * power(base,exponent-1,true);
else return 1;
}
int root(int A, int root) {
return power(E,(1000000000000/root)*(1-(power(A,-0.000000000001))));
}
I am having the hardest time figuring out what is wrong here:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fact(double);
double sinTaylor(double);
double cosTaylor(double);
int main()
{
double number, sineOfnumber, cosineOfnumber;
cout << "Enter a number, then I will calculate the sine and cosine of this number" << endl;
cin >> number;
sineOfnumber = sinTaylor(number);
cosineOfnumber = cosTaylor(number);
cout << fixed << endl;
cout << cosineOfnumber << endl;
cout << sineOfnumber << endl;
return 0;
}
double fact(double n)
{
double product = 1;
while(n > 1)
product *= n--;
return product;
}
double sinTaylor(double x)
{
double currentIteration, sumSine;
for(double n = 0; n < 5; n++)
{
currentIteration = pow(-1, n)*pow(x, 2*n+1) / fact(2*n+1);
sumSine += currentIteration;
}
return sumSine;
}
double cosTaylor(double y)
{
double currentIteration, sumCosine;
for(double n = 0; n < 5; n++)
{
double currentIteration = pow(-1, n)*pow(y, 2*n) / fact(2*n);
sumCosine += currentIteration;
}
return sumCosine;
}
Ok, so here's my code. I'm pretty content with it. Except for one thing:
sineOfnumber and cosOfnumber, after the calling of sinTaylor and cosTaylor, will add each other in the following cout line that will print each other.
In other words, if number is equal to lets say, .7853, 1.14 will be printed in the line that is intended to print cosineOfnumber, and sineOfnumber will print the result normally.
Can anyone help me identify why this is? Thank you so much!
Are you ever initializing the variables sumSine and sumCosine in your functions? They're not guaranteed to start at zero, so when you call += inside your loop you could be adding computed values to garbage.
Try initializing those two variables to zero and see what happens, as other than that the code seems okay.
The series for the sine is (sorry for the LaTeX):
sin(x) = \sum_{n \ge 0} \frac{x^{2 n + 1}}{(2 n + 1)!}
If you look, given term t_{2 n + 1} you can compute term t_{2 n + 3} as
t_{2 n + 3} = t_{2 n + 1} * \frac{x^2}{(2 n + 2)(2 n + 3)}
So, given a term you can compute the next one easily. If you look at the series for the cosine, it is similar. The resulting program is more efficient (no recomputing factorials) and might be more precise. When adding up floating point numbers, it is more precise to add them from smallest to largest, but I doubt that will make a difference here.