Babylonian square root algorithm output not matching example - c++

I'm doing an assignment and while I have it pretty much entirely done, I've run into a problem. The program is supposed to find the square root of a number the user inputs using the Babylonian square root algorithm. I was given an example output, and mine does not quite match. Also if you see any more issues please, give me a heads up! Especially if it's about the do while loop (it was the only solution I could get that stopped an infinite loop issue I was having).
#include <ios>
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
std::cout << std::fixed << std::setprecision(4);
//variables
int input;
double guess, r, check, test;
//input
cout << "Enter a number and I will apply the\n";
cout << "Babylonian square root algorithm until\n";
cout << "I am within .001 of the correct answer\n";
cin >> input;
cout << "You input " << input << "\n";
//calculate
guess = input / 2;
do {
test = guess;
r = input / guess;
guess = (guess + r) / 2;
cout << "\nguessing " << guess;
} while (guess != test); //while end
//check
check = guess * guess;
cout << "\nThe Babylons algorithm gives " << guess;
cout << "\nChecking: " << guess << " * " << guess << " = " << check << "\n";
} //main end
**Example output:**
Enter a number and I will apply the Babylonian square root algorithm
until I am withing .001 of the correct answer.
151
You entered 151
guessing 38.75
guessing 21.3234
guessing 14.2024
guessing 12.4172
guessing 12.2889
The Babylons algorithm gives 12.2889
Checking: 12.2889 * 12.2889 = 151.016
Press any key to continue . . .
**My Output:**
Enter a number and I will apply the
Babylonian square root algorithm until
I am within .001 of the correct answer
151
You input 151
guessing 38.5067
guessing 21.2140
guessing 14.1660
guessing 12.4127
guessing 12.2888
guessing 12.2882
guessing 12.2882
guessing 12.2882
The Babylons algorithm gives 12.2882
Checking: 12.2882 * 12.2882 = 151.0000

Change the type of input from int to double:
double input;
which changes initial value of guess = input / 2 from floor(151/2) = 75.0 to 75.5 for the expected sequence of values. Alternatively, cast the enumerator input to a double in the expression with:
guess = (double) input / 2;
or more elegantly via implicit type conversion by using floating point value as the divisor at suggested by #AlanBirtles:
guess = input / 2.0;
To fix the loop test:
#include <math.h>
...
do {
...
} while(fabs(test - guest) > 0.001);

Related

C++ Finding square root without sqrt function loop glitching

So I am making this as a homework assignment. I understand that there are so many ways that this code could be more efficient and accurate but this is the way my professor wants it done.
I am having problems with the loop. When I ask for the square root of 67 it does find it but it loops the correct answer 3 times.
Enter a value to be square rooted:
67
33.5
guess = 17.75
guess = 10.7623
guess = 8.49387
guess = 8.19096
guess = 8.18535
guess = 8.18535
guess = 8.18535
The program took 7 guess to find an estimation.
When I try to find the square root of 5 it finds it but continues to loop indefinitely
using namespace std;
int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;
cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess1 = squarenumber/2;
cout << guess1 << endl;
do
{
guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));
guess1 = guess2;
cout << "guess = " << guess2 << endl;
numofguess = numofguess + 1;
} while ((guess2 * guess2) > squarenumber);
cout<< "The program took "<< numofguess <<" guess to find an estimation.";
return 0;
}
I think that what you are missing is a proper exit condition.
Your code is written to loop indefinitely until the guess is "perfect".
You should have an exit condition checking if current guess is the same as previous guess, which obviously means that you won't do any better.
Here is my suggestion based on your code :
using namespace std;
int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;
cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess2 = guess1 = squarenumber/2;
cout << guess1 << endl;
const double epsilon = squarenumber * 1E-6;
do
{
guess1 = guess2;
guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));
cout << "guess = " << guess2 << endl;
numofguess = numofguess + 1;
} while ((guess2 * guess2) > squarenumber && fabs(guess2-guess1) > epsilon);
cout<< "The program took "<< numofguess <<" guess to find an estimation.";
return 0;
}
Mickaël C. Guimarães's answer is basically correct, check for an episolon value (absolute difference from the correct answer and your answer). But the "(guess2 * guess2) > squarenumber" should be dropped completely. That's because the value could in theory overshoot and be too low. The algorithm actually goes upwards if the value is too low. e.g. if you want SQRT(25) and your "guess1" prediction is way too low at 2, then guess2 would equal
(2 - (((2 * 2) - 25)/(2* 2))) = 7.25;
And on the next iteration then falls to 6.725624, so heads in the right direction. Low values actually get boosted up and eventually approach the target. By stopping if the value drops below the true SQRT then you might get "false positives" where too low values are accepted as accurate enough.
The times when the system got "stuck" were basically like the story Acchiles and the Tortoise. At each step, the system was dividing the remaining distance to go by some amount, but the change was therefore smaller each step, and could in theory never converge on the exact value, therefore you decide how much accuracy you want so that it finishes in a set time.
Additionally, the issue where the system seemed to take too many steps to converge is because floating point numbers are stored in higher precision, but cout has limited display precision. You can control that by sending setting values to cout before the print commands:
std::cout << std::fixed; // force all values to show to the same decimals
std::cout << std::setprecision(6); // set how many places to show
These code can be streamed to cout in one command before the value to print as well:
std::cout << std::fixed << std::setprecision(6) << "guess = " << guess2 << endl;

2 identical codes, get error at one

I added comments to the code, do I have a compiler issues? I can't figure it out, I tried looking on google and the book but I cant figure out why the first half of code only accepts the input with space between the number and unit and second code accepts the number and unit together.
I'm using code blocks. So far I tried closing it and opening it again.
int main(){
constexpr double dollar_to_euro = 0.91;
constexpr double dollar_to_yen = 117.07;
constexpr double dollar_to_pounds = 0.70;
double sum = 1;
char curr = '\0'; // tried replacing '\0' with '0' and ' '
cout << "Please enter sum, followed by currency for conversion.\n"
<< "U for dollar, E for euro, Y for yen and P for pounds.\n";
cin >> sum >> curr; // This is my issue, it does not want to accept "sumcurr" together, it only accepts it if theres space in between
// yet on the second code for inches or centimeters it does accept them being together. Look down.
// For example entering "5 E" works, yet "5E" does not work.
if(curr=='E')
cout << "The amount " << sum << " euro is " << sum/dollar_to_euro << " dollars\n";
else
cout << "GOD DAMMIT !!!!\n";
constexpr double cm_per_inch = 2.54;
double len = 1;
char unit = '\0';
cout << "Please enter length followed by unit.\n";
cin >> len >> unit; // Over here it works, this is an example from a book. Entering "5i" works.
if(unit=='i')
cout << len << " in == " << cm_per_inch*len << "cm.\n";
else
cout << "Wrong input !\n";
}
The problem here is that E/e is valid in a floating point number but 5E/5e is not a valid floating point number as you need a value after the E/e. So when you enter 5e the input for sum fails because of the invalid syntax where 5e0 would work. If you use anything other than E/e then it will work like your second example.
For more information on the format of floating point numbers see: Cppreference floating point literal

C Plus Plus not calculating correctly

I made a program that calculates the area of a circle. You have the option to enter a diameter or a radius. After you select one of them, you enter the value. Then it tells you what you entered and gives you the answer. But the answer isn't correct. For example, I enter 'r' then type '3' it gives me:
This is a calculator that calculates the area of a circle.
To get started, type 'd' (no quotes or caps) to enter a diamater.
Type 'r' (no quotes or caps) to enter a radius.
r
You chose radius, now please enter a number.
3
3 * 2 * 3.14 = 40828.1
It doesn't look right, as you can see. Perhaps C++'s Pi variable is outdated?
#include <iostream>
#include <math.h> // Importing math.h so I can use the M_PI variable.
using namespace std;
int main() {
char choice;
float result = 0.0; // Set to zero to init and stop the IDE from complaining.
float number = 0.0;
cout << "This is a calculator that calculates the area of a circle." << endl;
cout << "To get started, type 'd' (no quotes or caps) to enter a diamater." << endl;
cout << "Type 'r' (no quotes or caps) to enter a radius." << endl;
cin >> choice;
choice = tolower(choice); // Making it lower case so it's easier for compiler to recoginize.
switch (choice) {
case 'r':
cout << "You chose radius, now please enter a number." << endl;
cin >> number;
result = choice*choice*M_PI;
break;
case 'd':
cout << "You chose radius, now please enter a number." << endl;
cin >> number;
result = choice*M_PI;
break;
default:
cout << "You entered an invalid character. Please only enter 'r' or 'd' (no quotes or caps)" << endl;
break;
}
if (choice == 'r')
{
cout << number << " * 2 * 3.14 = " << result << endl;
}
else if (choice == 'd') {
cout << number << " * 3.14 = " << result << endl;
}
else {
cout << "Nothing here cause you didn't do simple stuff correctly..." << endl;
}
return 0;
}
Since you are new couple things you need to remember:
switch case and if/else statement are pretty similar, therefore you don't need to use them both at the same time on same task.
When the program runs the user inputs a value either r or d , that value get passed to the choice variable. The switch case compares its own cases to the choice value and if both value are equal, it will run that case code block and if they are not it will run the default code.
Now inside the case, you are asking for the radius, once you get the radius,
result = number * number * M_PI;
OR
result = pow(number,2.0) * M_PI;
And also there is a big difference between cout<<"2*3"; and cout<<2*3;
The first example will display 2*3 into your screen.
The second example will display the result of 2*3 into the screen
6, the reason you it calculates because there is not quotation mark around it
Hope that helps...
Shoulr calculation of result use choise???
Looks like you have a typo. Replace choise woth number in the
result = choice*choice*M_PI;
And in the
result = choice*M_PI;
Using choise in calculation actually uses its ASCII code. This explains the big values that you get in the result.
result = choice*choice*M_PI;
this should be
result = number * number * M_PI;
also you are printing
* 2 * 3.14 =
should be
^ 2 * 3.14 =

Getting an infinite loop in Babylonian Algorithm for square roots in C++

I have thoroughly searched for this topic all over the internet, and the threads are either dead, or use a different method than what is described in my book.
For example, http://www.geeksforgeeks.org/square-root-of-a-perfect-square/ . This doesn't work for me because my algorithm needs to loop until it reaches 1% of the last "guess".
Here is the question from the text.
The Babylonian algorithm to compute the square root of a number n is as follows:
Make a guess at the number (you can pick n/2 as your initial guess).
Compute r = n / guess
Set guess = (guess + r) / 2
Go back to step 2 for as many iterations as necessary. The more that steps 2 and 3 are repeated, the closer guess will become to the
square root of n.
Write a program that inputs an integer for n, iterates through the
Babylonian algorithm until guess is within 1% of the previous guess,
and outputs the answer as a double.
I have written the following code:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{
int n;
double r, guess(4), lastGuess;
cout << "Enter a number to find the square root of: ";
cin >> n;
do
{
r = n / guess;
lastGuess = guess;
guess = ( guess + r ) / 2;
// cout <<"Guess: " << guess << endl;
// cout <<"Last Guess: " << lastGuess << endl;
cout << "Guess : " << guess << endl;
cout << "Last Guess 1% = " << lastGuess + ( lastGuess * 0.01 ) << endl;
cout << "r = " << r << endl;
} while( guess >= lastGuess * 0.01 );
cout << r;
return 0;
}
The program computes the right answer for r, but the loop doesn't terminate despite guess being greater than 1% added to lastGuess.
This program produces the following output when inputting 144 as n.
....
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
....
The root (r) is correct (12). The guess is LESS than lastGuess (12 < 12.12), which should return a false to the condition, correct?. Why is the loop not ending?
If you want to add 1% you need to multiply by 1.01, not 0.01.
while( guess >= lastGuess * 1.01 );
By the way, this iterates while guess is growing by more than 1%. You should also allow for the opposite, that it may have shrunk by more than 1%. The approximation could approach the answer from either direction. (It will approach positive roots from the right and negative roots from the left.)
While printing your lastGuess you are using
lastGuess + ( lastGuess * 0.01 )
But while checking loop condition you are using
lastGuess*0.01
So in loop condition use the same equation which you are using for printing lastGuess value.
To properly exit the loop, use something similar to this.
void f(int N)
{
double x = N / 4;
double prev = 0.0f;
while(1)
{
x = 0.5 * (x + N / x);
if (prev == x)
break;
prev = x;
printf("val: %f\n", x);
}
printf("SQRT(%d) = %f\n", N, x);
}
I had the same problem in my book. This is what I wrote and it works perfect.
#include <iostream>
using namespace std;
int main()
{
double guess, root, previousGuess;
int number;
cout << "Enter a number to find the Babylonian square root.\n";
cin >> number;
cout << "You want to find the square root of " << number << ".\n";
cout << "Enter a guess for the square root.\n";
cin >> guess;
do
{
root = number / guess;
previousGuess = guess;
guess = (guess + root ) / 2;
} while(guess < 0.99*previousGuess || guess > 1.01*previousGuess);
cout << "The answer is " << guess << ".\n";
return 0;
}

c++ how to have a user input equation to be evaluated

My program is meant to ask a user to input an equation. Then find the maximum over an interval given by the user. When I compile my program, the output I get is:
Please complete the equation to be evaluated f(x)=
Please enter the first number of the interval to be checked:
Please enter the last number of the interval to be checked:
Please enter the desired initial step size:
sh: PAUSE: command not found
with the last line repeating many times.
I think the problem here has something to do with having the user input the equation to be tested. However, I'm unsure of how to fix this.
Here's my code
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int main()
{
int a, b, delta, fx, x, y;
int max = 0;
cout <<"Please complete the equation to be evaluated f(x)= " << endl;
cin >> fx;
cout <<"Please enter the first number of the interval to be checked: " << endl;
cin >> a;
cout << "Please enter the last number of the interval to be checked: " << endl;
cin >> b;
cout << "Please enter the desired initial step size: " << endl;
cin >> delta;
for(x = a; x <= b; x = x+delta)
{
y = fx;
if (y > max)
{
max = y;
cout <<"The maximum over the interval from " << a <<"to " << b <<"is " << delta;
}
else
{
delta= delta/2;
}
if (delta < pow( 10, -6))
{
system ("PAUSE");
}
}
return 0;
}
F(x) shouldn't be an integer variable, it should be a string variable. That way, the user can enter operators as characters instead of the compiler thinking they should be numbers. You would then have to process the string to determine the equation; this would require some thought, and possibly a more advanced data structure such as a binary tree.
Simply don't use system("pause"); in the if statement and you'll lose that error:
"sh: PAUSE: command not found". Place it right before the end of the main.
system("pause");
return 0;
As pointed out by others, the form of f(x) could be an issue with the above code.
Consider to redesign what to achieve for your program. One possibility is to narrow down the f(x) as polynomial function so that you can avoid parsing general algebraic equation, in this case you can ask:
how many degree of the polynomial ? upon this, it is followed by input the coefficient value for each factor in the polynomial equation.
This way, you can still use integer (or double - better) in the program.