how to use math in c++ - c++

When I give my n a value of 1 why does the result equal to 2 and not 3. Here is my code
#include <stdio.h>
int main()
{
int n;
float result;
scanf("%d", &n);
result = 1 + n/(2*n+1)*3/2;
while (n != 1)
{
result = result*(n-1)/(2*(n-1)+1);
n = n-1;
}
result = result * 2;
printf("%f", result);
return 0;
}

Since n is an int, the math on the right side is done as integer math, not float. Then the results is promoted to float to store into result.
result = 1 + n/(2*n+1)*3/2;
result = 1 + 1/3*3/2;
result = 1 + 1;
result = float(2);
Use float constants to get it to actually calculate as a float.
result =1.0f + n/(2.0f*n+1.0f)*3.0f/2.0f;

Related

C++ compound assignment and type conversion issue

I am calculating combination(15, 7) in C++.
I first used the following code and get the wrong answer due to a type promotion error.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 2520
So I changed ans *= (a + 1 - i) / i; to ans *= (double)(a + 1 - i) / i; and still get the wrong answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (double) (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6434
Finally, I tried ans = ans * (a + 1 - i) / i, which gives the right answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans = ans * (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6435
Could someone tell me why the second one did not work?
If you print out ans without casting it to (int) you'll see the second result is 6434.9999999999990905052982270717620849609375. That's pretty darn close to the right answer of 6535, so it's clearly not a type promotion error any more.
No, this is classic floating point inaccuracy. When you write ans *= (double) (a + 1 - i) / i you are doing the equivalent of:
ans = ans * ((double) (a + 1 - i) / i);
Compare this to the third version:
ans = ans * (a + 1 - i) / i;
The former performs division first followed by multiplication. The latter operates left to right and so the multiplication precedes the division. This change in order of operations causes the results of the two to be slightly different. Floating point calculations are extremely sensitive to order of operations.
Quick fix: Don't truncate the result; round it.
Better fix: Don't use floating point for integral arithmetic. Save the divisions until after all the multiplications are done. Use long, long long, or even a big number library.
First one did not work because you have integer division there.
Difference btw second one and third one is this:
ans = ans * (double(a + 1 - i) / i); // second is equal to this
vs:
ans = (ans * (a + 1 - i)) / i; // third is equal to this
so difference is in order of multiplication and division. If you round double to integer instead of simply dropping fractional part you will get the same result.
std::cout << int( ans + 0.5 ) << std::endl;

Basic C++ Recursion

I am trying to count series of: 1/2 + 1/3 + 1/4 + 1/5 + ...
But I had problem with my output:
Insert how many series's number will be counted : 3 // I am input 3
Total = 1 // This is the problem, the output should shown = 1.8333
My program
#include <iostream>
#include <math.h>
using namespace std;
int recursion ( int n );
int main ()
{
int n;
cout << "Insert how many number will be counted : ";cin >> n;
cout << "Total = " << recursion(n);
}
int recursion (int a)
{
int result;
if ( a >= 1 )
{
result = 1;
}
else
{
result = ( pow ( a , -1 ) + recursion ( pow ( ( a - 1 ) , -1 ) ) );
}
return (result);
}
As others have said, use floating point types, such as double or float.
In integer division, 1/3 == 0.
Here's an iterative example:
const unsigned int NUMBER_OF_TERMS = 100;
double result = 0.0;
double denominator = 2.0;
for (unsigned int i = 0; i < NUMBER_OF_TERMS; ++i)
{
result = result + 1.0 / denominator;
denominator = denomenator + 1.0;
}
Your code should use floating point constants (with decimal points) and floating point variables (of type double or float).
Edit 1: Basic recursion
In some cases of recursion, thinking of the solution backwards may help the implementation.
For example, the series starts with 1.0/2.0. However, since the sum operation doesn't depend on order, we can start with 1.0/5.0 and work backwards:
result = 1.0/5.0 + 1.0/4.0 + 1.0/3.0 + 1.0/2.0
This allows the denominator to be used as the condition for ending the recursion.
double recursive_sum(double denominator)
{
if (denominator < 2)
{
return 0.0;
}
return recursive_sum(denominator - 1.0)
+ 1.0 / denominator;
}

Multiplying integers the long way

I'm trying to create long int multiplication function. In math for multiplying 2 numbers for example 123 X 456, I do:
(12 * 10^1 + 3)( 45 * 10^1 + 6) =
(540 * 10^2) + (72 * 10^1) + (135 * 10^1) + 18 = 15129
I created a small program for this algorithm but it didn't work right.
I don't know where my problem is. Can you help me to understand and correct that?
Tnx
int digits(int n) {
int digit = 0;
while (n>0){
n/=10;
digit++;
}
return digit;
}
long int longMult(long int a, long int b) {
long int x,y,w,z;
int digitA = digits(a);
int digitB = digits(b);
if((a==0) || (b==0)) {
return 0;
} else if (digitA < 2 || digitB < 2) {
return a*b;
} else {
int powA = digitA / 2;
int powB = digitB / 2;
//for first number
x = a/(10^powA);
y = a%(10^powA);
//for second number
w = b/(10^powB);
z = b%(10^powB);
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
}
}
int main()
{
cout << digits(23) << endl; // for test
cout << longMult(24,24); // must be 576 but output is 96
return 0;
}
The expression
10^powA
does a bitwise exclusive or, and doesn't raise 10 to the power of powA, as you appear to expect.
You may want to define something like
long powli(int b, long e) {return e?b*powli(b,e-1):1;}
Then instead you can use
powli(10,powA)
Edit: There is also a problem with the way the values are combined:
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
Look into the maths, because multiplying the exponents makes little sense.
Also the combinations of adjustments to values is wrong, eg (10*a + b)(10*c + d) = 10*10*a*c + 10*a*d + 10*b*d +b*d. So check on your algebra.

Calculating a Sum with C++

I wrote the following code to sum the series (-1)^i*(i/(i+1)). But when I run it I get -1 for any value of n.
Can some one please point out what I am doing wrong? Thank you in advance!
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
int i = 1.0;
int n = 5.0;
for(i=1;i<=n;i++)
sum = (-1)^i*(i/(i+1));
cout << "Sum" <<" = "<< sum << endl;
return 0;
}
Problem #1: The C++ ^ operator isn't the math power operator. It's a bitwise XOR.
You should use pow() instead.
Problem #2:
You are storing floating-point types into an integer type. So the following will result in integer division (truncated division):
i/(i+1)
Problem #3:
You are not actually summing anything up:
sum = ...
should be:
sum += ...
A corrected version of the code is as follows:
double sum = 0;
int i = 1;
int n = 5;
for(i = 1; i <= n; i++)
sum += pow(-1.,(double)i) * ((double)i / (i + 1));
Although you really don't need to use pow in this case. A simple test for odd/even will do.
double sum = 0;
int i = 1;
int n = 5;
for(i = 1; i <= n; i++){
double val = (double)i / (i + 1);
if (i % 2 != 0){
val *= -1.;
}
sum += val;
}
You need too put sum += pow(-1,i)*(i/(i+1));
Otherwise you lose previous result each time.
Use pow function for pow operation.
edit : as said in other post, use double or float instead of int to avoid truncated division.
How about this
((i % 2) == 0 ? 1 : -1)
instead of
std::pow(-1, i)
?
Full answer:
double sum = 0;
int i = 1.0;
int n = 5.0;
for (i = 1; i <= n; ++i) {
signed char sign = ((i % 2) == 0 ? 1 : -1);
sum += sign * (i / (i+1));
}
Few problems:
^ is teh bitwise exclusive or in c++ not "raised to power". Use pow() method.
Remove the dangling opening bracket from the last line
Use ints not floats when assigning to ints.
You seem to have a few things wrong with your code:
using namespace std;
This is not directly related to your problem at hand, but don't ever say using namespace std; It introduces subtle bugs.
int i = 1.0;
int n = 5.0;
You are initializaing integral variables with floating-point constants. Try
int i = 1;
int n = 5;
sum = (-1)^i*(i/(i+1));
You have two problems with this expression. First, the quantity (i/(i+1)) is always zero. Remember dividing two ints rounds the result. Second, ^ doesn't do what you think it does. It is the exclusive-or operator, not the exponentiation operator. Third, ^ binds less tightly than *, so your expression is:
-1 xor (i * (i/(i+1)))
-1 xor (i * 0)
-1 xor 0
-1
^ does not do what you think it does. Also there are some other mistakes in your code.
What it should be:
#include <iostream>
#include <cmath>
int main( )
{
long sum = 0;
int i = 1;
int n = 5;
for( i = 1; i <= n; i++ )
sum += std::pow( -1.f, i ) * ( i / ( i + 1 ) );
std::cout << "Sum = " << sum << std::endl;
return 0;
}
To take a power of a value, use std::pow (see here). Also you can not assign int to a decimal value. For that you need to use float or double.
The aforementioned ^ is a bitwise-XOR, not a mark for an exponent.
Also be careful of Integer Arithmetic as you may get unexpected results. You most likely want to change your variables to either float or double.
There are a few issues with the code:
int sum = 0;
The intermediate results are not integers, this should be a double
int i = 1.0;
Since you will use this in a division, it should be a double, 1/2 is 0 if calculated in integers.
int n = 5.0;
This is an int, not a floating point value, no .0 is needed.
for(i=1;i<=n;i++)
You've already initialized i to 1, why do it again?
sum = (-1)^i*(i/(i+1));
Every iteration you lose the previous value, you should use sum+= 'new values'
Also, you don't need pow to calculate (-1)^i, all this does is switch between +1 and -1 depending on the odd/even status of i. You can do this easier with an if statement or with 2 for's, one for odd i one for even ones... Many choices really.

Recursive function returns unexpected result

My funciton takes a number input from the user and recursively sums the number 'n' to one.
Inputting a 5 would sum 1/5 + 1/4 + 1/3+ 1/2 + 1/1.
#include<stdio.h>
#include<conio.h>
//to
float recursion(float num,float sum);
void main(void)
{
float num=5,sum=0;
//input num
printf("%d",recursion(num,sum));
getch();
}
float recursion(float num,float sum)
{
// int sum=0; every time u run it the sum is assigned 0
if( num==1)
return 1;
else
{
sum=sum+(1/num);
num--;
recursion(num,sum);
}
return sum;
}//recursion function ends
The problem is, that it is giving 0. Can anyone help, please?
You should return the result of the recursive call:
return recursion(num,sum);
instead of return sum.
Why's the printf("%d") while it's supposed to print a float? Doesn't that display an integer making it always 0 for a float less than 0?
float recursion(float num)
{
if( num==1.0f)
{
printf("1/1 = ");
return 1.0f;
}
float inverse = 1.0f/num;
printf("1/%.0f + ", num);
return (inverse + recursion(--num));
}//recursion function ends
Here's the test code:
float num=5,sum=0;
float expected = 0;
for (int i = 1; i <= num; ++i)
{
expected += 1.0f/i;
}
//input num
printf("Expected %f and got %f",expected, recursion(num));
Output:
1/5 + 1/4 + 1/3 + 1/2 + 1/1 = Expected 2.283334 and got 2.283334
Hope this helps.
float recursion(float num) {
if( num==1)
return 1;
return (1.0/num) + recursion(num - 1);
}
By the way, do not input a negative number!
#fahad: Changes in your code has been commented in the code below:
float recursion2(float num,float sum)
{
// int sum=0; every time u run it the sum is assigned 0
if( num==1)
// Vite Falcon: Needs to return sum + 1
return sum + 1.0f;
else
{
// Vite Falcon: This is not really necessary.
//sum=sum+(1/num);
float inverse = 1.0f/num;
num--;
// Vite Falcon: The new sum is returned by the recursive function and so
// should be stored and returned.
sum = recursion2(num,sum + inverse);
}
return sum;
}//recursion function ends
PS: Sorry I had to answer again because I don't know how to add multi-line code as a comment.
Use sum=sum+(1.0/num);. When you divide 1, an integer with a float, the float gets converted to integer first.
float recursion(int num) {
if (num == 0) {
return 0;
}
return 1 / num + recursion(num--);
}