I am trying to solve a very simple equation in c++ by brute force. The basic idea is to run up or down the value of x until the left side of the equation is equal to the right side. I am not getting any errors, but the value of x is always either 0.01 or -0.01. I assume that my do/while loop is flawed, but you are all probably more experienced than I am, so any help is appreciated.
#include <iostream>
using namespace std;
int main()
{
double x, y, z, q, w;
x = 0;
cout << "enter y*x + q = z*x + w in order of appearance" << endl;
cin >> y;
cin >> q;
cin >> z;
cin >> w;
if ((y-z)/(w-q) > 0) // checks if x is positive
{
do
{
(x = x + 0.01);
} while ((y * x + q) == (z * x + w));
}
else if ((y - z) / (w - q) < 0) // checks if x is negative
{
do
{
(x = x - 0.01);
} while ((y * x + q) == (z * x + w));
}
else
{
x = 0;
}
cout << "x is " << x << endl;
return 0;
}
Thanks!
A few things.
First, when comparing floats, you probably want to do so within a tight range, frequently referred to as epsilon. This is especially true because you're incrementing by a fairly wide margin -- 0.01. You are probably skipping over the value you want.
What I would do is pay attention to:
Am I getting closer or further from the answer?
And did I skip over the answer?
Some code:
float leftSide = y * x + q;
float rightSide = z * x + w;
float delta = leftSide - rightSide;
if (abs(delta) < epsilon) {
// You're really close
}
Note also this will never work if y and z are identical values unless q and w are as well.
Related
I did a recursive function to calculate x*y with x and y are all integers (x and y >= 0). My formula is:
x * y =
0, if x is equal 0
(x >> 1)*(y << 1), if x is an even number
(x >> 1)*(y << 1) + y, if x is an odd number
"<<" and ">>" are Left Shift and Right Shift Bitwise Operator. Here is my code:
int multiply(int x, int y) {
int y1 = 0;
if (x == 0) return 0;
else if (x % 3 == 0) {
y1 = y;
x = x >> 1;
y = y << 1;
return (multiply(x, y) + y1);
}
else if (x % 2 == 0) {
x = x >> 1;
y = y << 1;
return multiply(x, y);
}
}
The recursive function above is supposed to return (x*y) value but they were all wrong when i tested and i don't know why. What did i do wrong? How can i fix this?
Your problem is wit x % 3, what happens if x = 5? you skip it. Here is improved version of your code.
int multiply(int x, int y) {
if (x == 0)
return 0;
else if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
return multiply(x >> 1, y << 1);
}
or maybe even this:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x % 2 == 1)
m += y;
return m;
}
Here is super fast version suggested by Andy:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x & 1)
m += y;
return m;
}
As a challenge of speed, here is non recursive version:
int multiply (int x, int y) {
int y1 = 0;
for (; x > 0; x = (x >> 1), y = (y << 1))
if (x&1)
y1 += y;
return y1;
}
NOTE: I know this question is about recursive method but just as a challenge I wrote non-recursive algorithm.
You are not checking if x is odd correctly here:
else if (x % 3 == 0) { // e.g. fails on x = 1
Instead, you need to do
else if (x % 2 == 1) {
Here's a demo.
Note that this makes the following else check for even values of x redundant:
else if (x % 2 == 0) { // can just be an unconditional else
Also, since you are returning from the x == 0, and x % 2 == 1 branches, the else conditions can be removed as well. You can also factor out the repeated code to make the function simpler, like this:
int multiply(int x, int y) {
if (x == 0) return 0;
if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
else
return multiply(x >> 1, y << 1);
}
Here's a demo.
This is what i feel is the simplest approach to carry out recursive multiplication.
Do let me know if its efficient enough for you.
#include<iostream>
using namespace std;
float multiply(float a, float b) {
//no zeros bro
if (b == 0)
return 0;
//let the recursion begin
if (b > 0)
return x + multiply(a, b - 1);
//negatives stay away pliz
if (y < 0)
return -multiply(a, -b);
}
int main() {
float a, b, result;
cout << "Enter the two numbers";
cin >> a >> b;
result = multiply(a, b);
//And the result is.................
cout << result;
return 0;
}
Recursive function related to multiplication of natural numbers:
int multCool(int a, int b)
{
return (b==1 ? a: a+ multCool(a,b-1));
}
I've recently been given a problem by my teacher about some mathematical equation / formula called the arctanx formula. The question is:
According to the Arctanx(x) = x - ((x ^ 3) / 3) + ((x ^ 5) / 5) - ((x ^
7) / 7) + ...and π = 6 * arctanx(1 / sqrt(3)), Create function arctanx(x)
, and find pi when the last "number"(like this ((x ^ y) / y)) is right before
and bigger than 10 ^ -6, or you can say that no "number" can be smaller than
that number without being smaller than 10 ^ -6.
I tried to code it out, but there is a bug in it.
# include<iostream>
# include<math.h>
using namespace std;
float arctanx() {
long double pi = 3.1415926535897;
int i = 0; // 0 = +, 1 = -
float sum = 0;
float lsum;
for (int y = 1; y < pi; y += 2) {
if (lsum > 0.000001) {
if (i == 0) {
lsum = pow(1 / sqrt(3), y) / y;
sum += pow(1 / sqrt(3), y) / y;
i++;
} else if (i == 1) {
lsum = pow(1 / sqrt(3), y) / y;
sum -= pow(1 / sqrt(3), y) / y;
i--;
}
} else {
break;
}
}
sum = sum * 6;
return sum;
}
int main() {
cout << arctanx();
return 0;
}
It should have a output of some number not equal to zero, but I got 0 from running this.
Your program has Undefined Behavior because you are using the uninitialized float lsum; in the comparison if (lsum > 0.000001).
What probably happens in your case is that lsum happens to be less than or equal to 0.000001 and your for immediately breaks without doing anything causing your function to return 0 * 6 which is obviously 0.
Create function arctanx(x)
The function defined in the posted code doesn't accept any parameter, it just uses the hardwired (and repeated) value 1 / sqrt(3) and tries to return an approximated value of π instead of the arctangent of x.
It also has undefined behavior, beeing lsum uninitialized (therefore having an indeterminate value) when it is first used in the comparison inside the loop.
Consider this implementation, but be advised that this particular polinomial expansion diverges for values of x greater than 1.
#include <iostream>
#include <iomanip>
#include <cmath>
double arctanx(double x);
int main()
{
double pi = 6.0 * arctanx(1.0 / std::sqrt(3));
std::cout << std::setprecision(8) << pi << '\n';
}
double arctanx(double x)
{
// You can take advantage of a running power, instad of calculating
// pow(x, i) at every iteration
double sq_x = x * x;
double pow_x = x * sq_x;
double err = 1e-6;
// Instead of keeping track of the alternating sign, you can use
// two separate partial sums
double sum_pos_term = x;
double sum_neg_term = 0.0;
for (int i = 3; i < 33; i += 2) // <- Limit the number of iterations
{
if (pow_x < err * i)
break;
sum_neg_term += pow_x / i;
i += 2;
pow_x *= sq_x;
if (pow_x < err * i)
break;
sum_pos_term += pow_x / i;
pow_x *= sq_x;
}
return sum_pos_term - sum_neg_term;
}
While I was writing a c++ program I stuck on a problem. In brief, my program input is one integer which is the number of coordinates that I have to input. And I have an algorithm that calculates the passed distance between all of the points. Here is my algorithm:
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
const double PI = 3.14;
const double rightXLimit = 5;
const double leftXLimit = -5;
const double topYLimit = 2;
const double bottomYLimit = -2;
const int ARR_SIZE = 100;
bool IsPointInRules(double x, double y)
{
if ((x >= leftXLimit && x <= rightXLimit) && (y >= bottomYLimit && y <= topYLimit))
{
return true;
}
return false;
}
double checkLimitsAndDistCalc(double x, double y, double x1, double y1)
{
if (!(IsPointInRules(x, y) || IsPointInRules(x1, y1)))
{
return 0;
}
else if (IsPointInRules(x, y) && (!IsPointInRules(x1, y1)))
{
if (x1 <= leftXLimit)
{
x1 = leftXLimit;
}
if (x1 >= rightXLimit)
{
x1 = rightXLimit;
}
if (y1 <= bottomYLimit)
{
y1 = bottomYLimit;
}
if (y1 >= topYLimit)
{
y1 = topYLimit;
}
}
else if ((!IsPointInRules(x, y)) && IsPointInRules(x1, y1))
{
if (x <= leftXLimit)
{
x = leftXLimit;
}
if (x >= rightXLimit)
{
x = rightXLimit;
}
if (y <= bottomYLimit)
{
y = bottomYLimit;
}
if (y >= topYLimit)
{
y = topYLimit;
}
}
double distance = sqrt(pow(x1 - x, 2) + pow(y1 - y, 2));
double result = ((PI * distance / 2) + distance) / 2;
//cout << setw(3) << x << setw(3) << y << setw(3) << x1 << setw(3) << y1 << " --> " << distance << " --> " << result << endl;
return result;
}
double calculateDistance(double* arrOne, double* arrTwo, int n)
{
double finalResult = 0;
for (int i = 0; i < n - 1; i++)
{
double getDistance = checkLimitsAndDistCalc(arrOne[i], arrTwo[i], arrOne[i + 1], arrTwo[i + 1]);
finalResult += getDistance;
}
return finalResult;
}
int main()
{
double coordsArrX[ARR_SIZE];
double coordsArrY[ARR_SIZE];
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> coordsArrX[i];
cin >> coordsArrY[i];
}
cout << setprecision(3) << fixed << calculateDistance(coordsArrX, coordsArrY, n) << '\n';
}
The problem is when I enter integers like coordinates the distance is wrong, but when enter double the distance is right and I can not find where is the problem. Here I tried some auto tests:
The problem is when I enter integers like coordinates the distance is wrong, but when enter double the distance is right and I can not find where is the problem.
That is an incorrect conclusion. The output is same whether you enter the coordinates using what appears to be integers or floating point numbers.
The output obtained using
7
0 0
0 3
-2 4
-1 1
-3 -1
4 1
6 3
is the same as using
7
0.0 0.0
0.0 3.0
-2.0 4.0
-1.0 1.0
-3.0 -1.0
4.0 1.0
6.0 3.0
See the output from using floating point input at http://ideone.com/fxgbga.
It appears that there is something else in your program that is not working as you are expecting.
The function f(x) and the series need to end up with the same answer
This is my attempt on this task, but it gives me different results and I don't fully understand the concept of series in C++
#include <iostream>
#include <math.h>
#include <cstdlib>
using namespace std;
int main()
{
float x, y1, y2, a;
int n;
cout<<"Enter x: ";
cin>>x;
cout<<"Enter n: ";
cin>>n;
if (x == 0) x = 3.0;
y1 = 1.0/(2.0*x+5.0);
a = 1.0/11;
y2 = a;
cout<<"f(x) = "<<y1<<endl;
if(x > -5.0/2.0 && x < 17.0/2.0){
for (int k = 0; k <= n; k++){
a = (a*(-1)*pow(2.0/11.0,k))/pow(11.0,k);
y2 = y2 + a;
}
}
else{
return 1;
}
cout<<"Sum = "<<y2<<endl;
system("pause");
return 0;
}
I used any x from -2,5 to 8,5 and n up to 100
the results are always different...
the function and sum of the series are supposed to have very close, if not equal answers, but it's not in my case..
How am I supposed to do it? would be happy for an explanation)
You should probably just use the correct term for your sum:
a = pow(-2.0 / 11.0 * (x - 3), k) / 11.0;
Note that I combined the terms in the power. The division by 11 may also be moved to the end, saving some operations. But then you would need a different initialization. However, this would also allow you to calculate a incrementally. Something like this:
//Initialization
a = 1.0;
y2 = a;
double factor = -2.0 / 11.0 * (x - 3);
//...
for (int k = 1; k <= n; k++)
{
a *= factor;
y2 += a;
}
//Finally
cout << "Sum = " << y2 / 11.0f << endl;
This question already has answers here:
The most efficient way to implement an integer based power function pow(int, int)
(21 answers)
Closed 8 years ago.
I've read that cmath calculates pow(a,b) by performing exp(b*log(a)). This should not be used when b is an integer, since it slows down calculations a lot. What alternatives are there when
calculating a lot of successive pow()s with the same constant a
it is known beforehand that b will definitely be an integer?
I am looking for fast alternatives which are efficient in these particular scenarios.
There are a number of faster alternatives I've collected over the years that typically rely on a recursive implementation of the function, and bit shifts to handle multiplication when warranted. The following provide functions tailored to integer, float and double. They come with the normal disclaimer: while faster not all possible test have been run and the user should validate input is sane before calling and on return... blah, blah, blah.. But, they are pretty darn useful:
I believe proper attribution goes to Geeks for Geeks Pow(x,n) as pointed out by blue moon. I had long since lost the links.. That looks like them. (minus a tweak or two).
/* Function to calculate x raised to the power y
Time Complexity: O(n)
Space Complexity: O(1)
Algorithmic Paradigm: Divide and conquer.
*/
int power1 (int x, unsigned int y)
{
if (y == 0)
return 1;
else if ((y % 2) == 0)
return power1 (x, y / 2) * power1 (x, y / 2);
else
return x * power1 (x, y / 2) * power1 (x, y / 2);
}
/* Function to calculate x raised to the power y in O(logn)
Time Complexity of optimized solution: O(logn)
*/
int power2 (int x, unsigned int y)
{
int temp;
if (y == 0)
return 1;
temp = power2 (x, y / 2);
if ((y % 2) == 0)
return temp * temp;
else
return x * temp * temp;
}
/* Extended version of power function that can work
for float x and negative y
*/
float powerf (float x, int y)
{
float temp;
if (y == 0)
return 1;
temp = powerf (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
/* Extended version of power function that can work
for double x and negative y
*/
double powerd (double x, int y)
{
double temp;
if (y == 0)
return 1;
temp = powerd (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
Non-recursive non-floating point answer
Replace uintmax_t/intmax_t with the type of your desire. Overflow not detected.
uintmax_t powjuu(unsigned x, unsigned y) {
uintmax_t z = 1;
uintmax_t base = x;
while (y) {
if (y & 1) { // or y%2
z *= base;
}
y >>= 1; // or y /= 2
base *= base;
}
return z;
}
intmax_t powjii(int x, int y) {
if (y < 0) {
switch (x) {
case 0:
return INTMAX_MAX;
case 1:
return 1;
case -1:
return y % 2 ? -1 : 1;
}
return 0;
}
intmax_t z = 1;
intmax_t base = x;
while (y) {
if (y & 1) {
z *= base;
}
y >>= 1;
base *= base;
}
return z;
}
You may want to check this. It's a fast algorithm to replace the pow function.