finding nth root of a number by using divide and conquer method - c++

I need help on how to get nth root of some number.
User enters number n and number he wants root of. I need to solve this without cmath lib and with divide and conquer method.
Here's my code that doesn't work yet:
#include<iostream>
using namespace std;
float pow(float a,float c){
if (a == 0)
return 0;
else if(a == 1)
return 1;
else{
float p = pow(a,(c/2));
if(c%2)
return p*p*a;
else
return p*p;
}
}
int main(){
float a,b;
float c;
cout << "Enter positive number:(base)" << endl;
do{
cin >> a;
}while (a < 0);
cout << "Enter number: (root)" << endl;
cin >> b;
c = 1/b;
cout << "Result:"<<pow(a,c) << endl;
system("pause");
return 0;
}
Any ideas on how to approach this problem would be more than useful.

Let me tell you how you can use divide and conquer for finding square root. The nth root would be similar.
For a given number x, you need to search for it's square root between 0 and x. Divide it by 2 = x2. If the x2 * x2 < x then your search space moves to x2 -> x or else it will be 0 -> x2. If x2 * x2 matches x then your square root is x2. Similar technique for nth root.

For those not doing numerical experiments: use the <cmath> functions sqrt and cbrt (cube-root) to construct the any root that is factorable by 2 and 3. For example, the 4th root is sqrt(sqrt(x)) and the 6th root is sqrt(cbrt(x)). If you need something for general use you can construct a recursive function which calls sqrt and cbrt appropriately.
I'm guessing this will give a faster and more accurate answer than pow, if that matters. If it doesn't, just use pow.

Related

Getting a C++ double function to report a message instead of returning a numerical when a certain condition is met

I am very new to C++, and am trying to create a pair of functions that will report two possible real solutions to a quadratic equation. I am also trying to enter a message into these functions that will display in lieu of a solution if no real solution exists.
The functions correctly report real solutions, but when a non-real solution appears, the program will return "The two possible real solutions to this problem are nan and nan," and my error message ("There is no real solution to that quadratic equation. Please enter a different set of numbers") does not show up in the terminal at all.
Here is my code. Thank you in advance for your help!
#include <iostream>
#include "std_lib_facilities.h" // from a Github page by Bjarne Stroustrup that corresponds with the Programming: Practices and Principles book. Note that I am learning this on my own; it is not for homework.
#include <cmath>
double quafo1 (double a, double b, double c)
{
if ((sqrt((b*b)-(4*a*c))) < 0)
{
cout << ("There is no real solution to that quadratic equation. Please enter a different set of numbers;/n");
}
else {
double x1 = ((b * -1) + sqrt((b * b) - (4 * a * c))) / (2 * a);
return x1;
}
}
double quafo2 (double a, double b, double c)
{
if ((sqrt((b*b)-(4*a*c))) < 0)
cout << ("There is no solution to that quadratic equation. Please enter a different set of numbers;");
else {
double x2 = ((b * -1) - sqrt((b * b) - (4 * a * c))) / (2 * a);
return x2;
}
}
double a;
double b;
double c;
int main()
{
cout << "This program will solve a quadratic equation as long as one or more real solutions are possible. Please enter values for a, b, and c (separated by spaces and followed by enter, e.g. 3 5 4), after which both possible answers for x will be provided. Please note that a cannot equal 0.\n";
while (cin >> a >> b >> c)
{
cout << "The two possible real solutions to this problem are " << quafo1(a, b, c) << " and " << quafo2(a,b,c) << ".\n";
}
}
The sqrt function will never return a negative value*, so your test (sqrt((b*b)-(4*a*c))) < 0 will never be TRUE. What you probably want to do is test if the argument to sqrtis negative:
if (((b*b)-(4*a*c))) < 0) {
cout << ("There is no solution to that quadratic equation. Please enter a different set of numbers;");
return nan("");
}
else {
//...
Alternatively, if that argument is negative, the sqrt function will return NaN, which you can test for with the isnan() function:
if (isnan(sqrt((b*b)-(4*a*c)))) {
cout << ("There is no solution to that quadratic equation. Please enter a different set of numbers;");
//...
Feel free to ask for further clarification and/or explanation.
Note: Strictly speaking, any (positive) number has two square roots, one positive and one negative: 2 x 2 = 4 but also -2 x -2 = 4.
You could just return NaN itself in those cases:
https://en.cppreference.com/w/cpp/numeric/math/nan
I would suggest a few changes to the programme that fix the issues you are having.
#include <iostream>
#include "std_lib_facilities.h"
// from a Github page by Bjarne Stroustrup that corresponds with the Programming: Practices and Principles book. Note that I am learning this on my own; it is not for homework.
#include <cmath>
double quafo1(double a, double b, double c) {
if ((b*b-4*a*c) < 0)
return sqrt(-1);
else
return ((b * -1) + sqrt((b * b) - (4 * a * c))) / (2 * a);
}
double quafo2(double a, double b, double c) {
if ((b*b-4*a*c) < 0)
return sqrt(-1);
else
return ((b * -1) - sqrt((b * b) - (4 * a * c))) / (2 * a);
}
double a;
double b;
double c;
int main()
{
cout << "This program will solve a quadratic equation as long as one or more real solutions are possible. Please enter values for a, b, and c (separated by spaces and followed by enter, e.g. 3 5 4), after which both possible answers for x will be provided. Please note that a cannot equal 0.\n";
while (cin >> a >> b >> c) {
double s1 = quafo1(a,b,c),
s2 = quafo2(a,b,c);
if (s1==s1 && s2==s2)
cout << "The two possible real solutions to this problem are " << s1 << " and " << s2 << '.' << endl;
else
cout << "There is no real solution to that quadratic equation. Please enter a different set of numbers." << endl;
}
}
First of all, as #Adrian mentioned above, you need to check whether b*b-4*a*c is negative or not and not its square root.
Second, the function must return something in all cases. Hence, you must have a return statement for when there are no real solutions. In those cases, you may simply return NaN. One way to do that would be returning sqrt(-1) as I did. In fact, you can simply return the solution to the quadratic equation, which would be NaN if no real solutions are possible because the square root of b*b-4*a*c is involved.
Now, in main, you may check if the returned value is NaN. To check for that, you can use isnan(), or check if it is equal to itself, which I did over here. I hope this solves your problem.
An indirect answer is that C++ has exceptions, precisely when you cannot return a value. You can define your own exception classes, but std::out_of_range makes perfect sense here.
Exceptions are thrown like throw std::out_of_range("There is no real solution to that quadratic equation."); and caught with try { ... } catch (std::exception& e) { std::cerr << e.what() << " Please enter a different set of numbers";}
cout << ("There is no real solution to that quadratic equation. Please enter a different set of numbers;/n");
This line should be terminated with "\n", not "/n". "<< endl;" could be used

How to reset values in for loop?

I need help figuring out where my code went wrong. I want to reset the values for the loop so that it isn't compiling because my output right now is using past input values in current calculation whereas I want the output to be different every time as though it is the firs time running the code. The code works fine when I don't use the while loop, but then I have to rerun the program each time. I want the output to prompt a new input every time, but not use past inputs in the new calculations. I know I'm not explaining it very well, but I'm just sort of lost. Anything helps!
This is my problem:
An approximate value of pi can be calculated using the series given
below:
pi = 4 ยท [ 1 โ€“ 1/3 + 1/5 โ€“ 1/7 + 1/9 ... + (โ€“1 ^ n)/(2n + 1) ]
Write a C++ program to calculate the approximate value of pi using
this series. The program takes an input n that determines the number
of terms in the approximation of the value of pi and outputs the
approximation. Include a loop that allows the user to repeat this
calculation for new values n until the user says she or he wants to
end the program.
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n;
double sum=0;
cout << "Enter the number of terms to approximate (or zero to quit):\n";
cin >> n;
if (n == 0)
{
return 0;
}
while (n != 0)
{
{ for(int i=0;i<n;i++)
{
if (i%2==0)
{
sum += 1.0/(2*i+1);
}
else
{
sum += -1.0/(2*i+1);
}
}
cout.setf(ios::showpoint);
cout.precision(3);
cout << "The approximation is " << sum*4 << " using " << n << " terms." << endl;
}
cout << "Enter the number of terms to approximate (or zero to quit):\n";
cin >> n;
}
return 0;
}
This is my output:
This is what the output should be:
You do not reset sum before entering the for loop. Just add
sum=0;
before the for line.
Notice that 2.67 = 6.67 - 4.00.
You want your program to compute a sum for several values of n.
The sum must be initialized to 0 at the beginning of each calculation, inside the while loop.
Actually, it should even be declared there.
C++ doesn't require you to define variables at the start of a function, so it is perfectly legal to write:
while (n != 0)
{
double sum = 0.0;
this would solve your problem. Alternatively, if you want to keep the declaration of sum at the top of the function, just change your code to
while (n != 0)
{
sum = 0.0;

for loop help. Terminates when it isnt supposed to. c++

I'm new to stackoverflow, but i did try to look for an answer and could not find it. I also can't seem to figure it out myself. So for a school C++ project, we need to find the area under a curve. I have all the formulas hardcoded in, so don't worry about that. And so the program is supposed to give a higher precision answer with a higher value for (n). But it seems that when I put a value for (n) thats higher than (b), the program just loops a 0 and does not terminate. Could you guys help me please. Thank you. Heres the code:
/* David */
#include <iostream>
using namespace std;
int main()
{
cout << "Please Enter Lower Limit: " << endl;
int a;
cin >> a;
cout << "Please Enter Upper Limit: " << endl;
int b;
cin >> b;
cout << "Please Enter Sub Intervals: " << endl;
int n;
cin >> n;
double Dx = (b - a) / n;
double A = 0;
double X = a;
for (X = a; X <= (b - Dx); X += Dx)
{
A = A + (X*X*Dx);
X = X * Dx;
cout << A << endl;
}
cout << "The area under the curve is: " << A << endl;
return 0;
}
a, b, n are integers. So the following:
(b - a) / n
is probably 0. You can replace it with:
double(b - a) / n
Since all the variables in (b - a) / n are int, you're doing integer division, which discards fractions in the result. Assigning to a double doesn't change this.
You should convert at least one of the variables to double so that you'll get a floating point result with the fractions retained:
double Dx = (b - a) / (double)n;
The other answers are correct. Your problem is probably integer division. You have to cast on of the operands to double.
But you should use static_cast<> instead of C-style casts. Namely use
static_cast<double>(b - a) / n
instead of double(b - a) / n or ((double) (b - a)) / n.
You are performing integer division. Integer division will only return whole numbers by cutting off the decimal:
3/2 == 1 //Because 1.5 will get cut to 1
3/3 == 1
3/4 == 0 //Because 0.5 will get cut to 0
You need to have at least one of the two values on the left or right of the "/" be a decimal type.
3 / 2.0f == 1.5f
3.0f / 2 == 1.5f
3.0f / 2.0f == 1.5f

Calculation issue in C++

So in this program i am trying to print out the standard deviation of a set of numbers the user enters in. The formula to calculate standard deviation is correct (or as correct as it needs to be) so that is not the problem, but when i run the program everything goes well until the console prints out the results. It prints that totalStandardDeviation = nan
what exactly does than mean? is nan the same as nil? has it lost the value somehow and not been able to find it? thanks for any help you may provide.
#include <iostream>
#include <cmath>
using namespace std;
double returnStandardDeviation(double x, int counter);
double total;
int userInput = 1;
int counter = 0;
double x;
double x1;
double x2;
double standardDeviation;
double totalStandardDeviation;
int main(int argc, const char * argv[])
{
cout << "Please enter a list of numbers. When done enter the number 0 \n";
cin >> userInput;
while (userInput != 0) // As long as the user does not enter 0, program accepts more data
{
counter++;
x = userInput;
returnStandardDeviation( x, counter); // send perameters to function
cout << "Please enter next number \n";
cin >> userInput;
}
cout << "The standard deviation of your "
<< counter
<< " numbers is : "
<< returnStandardDeviation(x, counter);
return 0;
}
double returnStandardDeviation(double x, int counter)
{
x1 += pow(x,2);
x2 += x;
totalStandardDeviation = 0;
totalStandardDeviation += (sqrt(counter * x1 - pow(x2,2))) / (counter * (counter - 1));
return totalStandardDeviation;
}
NaN stands for "Not a number".
NaN can e.g. be the result of:
- Dividing by zero
- Taking the square root of a negative number
In your function, both of these could happen. Division by zero e.g. when counter is <= 1; and x1 and x2 are uninitialized (+= adds the value on the right to their current value - which was never set, and is therefore random gibberish), which can easily lead to your function trying to take the square root of some value < 0.
This expression
counter * x1 - pow(x2,2)
can very easily yield a negative number. You then proceed to take its square root. This would result in a nan.
Next, this one
counter * (counter - 1)
yields 0 when counter is 1. Dividing by zero gives nan.
Your formula is wrong. You are either dividing by zero or taking the square root of a negative number.
Check your formula!
Additional info:
NaN is "Not a number". It is an IEEE floating point value that signals an invalid results, like log(-1), or sqrt(-4).
Additionally, know that Positive Infinity and Negative Infinity are also floating point values.

Nan results when iterating using sin and cos functions

I'm compiling this program using Code::Blocks 10.05 however normally I will get about 10 iterations done before it starts producing Nan in every single output. I was wondering if this is a problem caused by using the cos and sin functions and if there was a decent work around to avoid this?
I have to produce a lot of iterates because I am working on a project for University so it has to be accurate too. I looked up a few articles about how to avoid using sin and cos though I need to follow a few formulas rigorously otherwise the results I produce may be inaccurate so I'm not sure whether to compromise.
struct Particle // Need to define what qualities our particle has
{
double dPosition;
double dAngle;
};
Particle Subject;
void M1(double &x, double &y) //Defines movement if particle doesn't touch inner boundary
{
x = x + 2*y;
}
double d = 0.25; //This can and will be changed when I need to find a distance between
// the two cricles at a later stage
void M2(double &x,double &y, double d) //Defines movement of a particle if it impacts the inner boundary
{
double z = asin(-(sin(y)+d*cos(x + y))/0.35);
double y1 = y;
y = asin(-0.35*sin(z) + d*cos(x + y + 2*z));
x = y + y1 + x + 2*z;
}
int main()
{
cout << "Please tell me where you want this particle to start positions-wise? (Between 0 and 2PI" << endl;
cin >> Subject.dPosition;
cout << "Please tell me the angle that you would like it to make with the normal? (Between 0 and PI/2)" << endl;
cin >> Subject.dAngle;
cout << "How far would you like the distances of the two middle circles to be?" << endl;
double d;
cin >> d;
// These two functions are to understand where the experiment begins from.
// I may add a function to change where the circle starts however I will use radius = 0.35 throughout
cout << "So position is: " << Subject.dPosition << endl;
cout << "And angle with the normal is: " << Subject.dAngle <<endl;
int n=0;
while (n <= 100) //This is used to iterate the process and create an array of Particle data points
{ // in order to use this data to build up Poincare diagrams.
{
while (Subject.dPosition > 2*M_PI)
Subject.dPosition = Subject.dPosition - 2*M_PI;
}
{
if (0.35 >= abs(0.35*cos(Subject.dPosition + Subject.dAngle)+sin(Subject.dAngle))) //This is the condition of hitting the inner boundary
M2(Subject.dPosition, Subject.dAngle, d); //Inner boundary collision
else
M1(Subject.dPosition, Subject.dAngle); // Outer boundary collision
};
cout << "So position is: " << Subject.dPosition << endl;
cout << "And angle with the normal is: " << Subject.dAngle <<endl;
n++;
}
return 0;
}
Nan is shown in c++ as an indication of infinite, zero devision, and some other variations of non representable numbers.
Edit:
As pointed by Matteo Itallia, inf is used for infinite/zero division. I found these approaches:
template<typename T>
inline bool isnan(T value) {
return value != value;
}
// requires #include <limits>
template<typename T>
inline bool isinf(T value) {
return std::numeric_limits<T>::has_infinity &&
value == std::numeric_limits<T>::infinity();
}
Reference: http://bytes.com/topic/c/answers/588254-how-check-double-inf-nan
If the value is outside of [-1,+1] and passed to asin(), the result will be nan
If you need to check for Nan, try the following
if( value != value ){
printf("value is nan\n");
}