Apr 1, 2013 at 5:09am UTC
Hello. I require constructive criticism for my new quadratic equation calculator, 2.0
Thank you.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
int main()
{
string use_again;
string a_var_s;
long double a_var = 0;
string b_var_s;
long double b_var = 0;
string c_var_s;
long double c_var = 0;
long double b_var_sqrd = 0;
long double discriminant = 0;
unsigned int discriminant_indication = 0;
long double divisor = 0;
long double dividend = 0;
long double root_var = 0;
long double res = 0;
long double res_2 = 0;
string correct_equation;
string correct_equation_validation;
do {
cout << endl;
cout << "Quadratic equation calculator, 2.0." << endl;
cout << endl;
cout << "This program only calculates quadratic equations that are in ax^2 + bx + c = 0 form." << endl;
cout << endl;
cout << "This form is also known as standard form." << endl;
cout << endl;
while ( correct_equation != "y" )
{
cout << "Input the value of a:" << endl;
getline ( cin, a_var_s );
stringstream( a_var_s ) >> a_var;
cout << "Input the value of b:" << endl;
getline ( cin, b_var_s );
stringstream( b_var_s ) >> b_var;
cout << "Input the value of c:" << endl;
getline ( cin, c_var_s );
stringstream( c_var_s ) >> c_var;
cout << endl;
cout << "Did you mean to input the following equation: " << a_var << "x^2" ;
if ( b_var >= 0 )
cout << "+" << b_var << "x" ;
else
cout << b_var << "x" ;
if ( c_var >= 0 )
cout << "+" << c_var;
else
cout << c_var;
cout << " = 0?" << endl;
cout << endl;
do {
cout << "Input 'y' if the equation was correct." << endl;
cout << "Input 'n' if the equation was incorrect." << endl;
cin >> correct_equation;
if ( correct_equation != "y" && correct_equation != "n" )
{
correct_equation_validation = "n" ;
cout << "Invalid user input. Please try again." << endl;
cout << endl;
}
else if ( correct_equation == "y" )
correct_equation_validation = "y" ;
else
{
correct_equation_validation = "y" ;
correct_equation = "n" ;
}
cin.ignore();
} while ( correct_equation_validation == "n" );
}
b_var_sqrd = pow ( b_var, 2 );
discriminant = b_var_sqrd - 4*a_var*c_var;
cout << "The discriminant of the equation is " << discriminant << "." << endl;
cout << "Therefore: " ;
if ( discriminant == 0 )
{
cout << "x can only have one real value." << endl;
discriminant_indication = 1;
}
else if ( discriminant < 0 )
{
cout << "x has no real values." << endl;
discriminant_indication = 0;
}
else
{
cout << "x has two real values." << endl;
discriminant_indication = 2;
}
root_var = sqrt( discriminant );
dividend = -1 * b_var + root_var;
divisor = 2 * a_var;
res = dividend/divisor;
if ( discriminant_indication == 1 )
cout << "x = " << res << "." << endl;
else if ( discriminant_indication == 2 )
{
cout << "x = " << res << "." << endl;
dividend = -1 * b_var - root_var;
divisor = 2 * a_var;
res_2 = dividend/divisor;
cout << "OR: x = " << res_2 << "." << endl;
}
cout << "Input 'y' to use this program again:" << endl;
cin >> use_again;
correct_equation = "n" ;
cin.ignore();
} while ( use_again == "y" || use_again == "Y" );
cin.get();
return 0;
}
Last edited on Apr 1, 2013 at 5:10am UTC
Apr 1, 2013 at 5:47am UTC
Last edited on Apr 1, 2013 at 5:53am UTC
Apr 1, 2013 at 5:55am UTC
MiiNiPaa,
How can I fix the rounding problems?
Apr 1, 2013 at 6:04am UTC
Also, I have been trying online quadratic equation calculators, that also calculate the discriminant, and even they calculate the incorrect discriminant.
Apr 1, 2013 at 6:26am UTC
Read the links I provided
Last edited on Apr 1, 2013 at 6:26am UTC
Apr 1, 2013 at 7:49am UTC
I do not understand the links provided.
Apr 1, 2013 at 8:03am UTC
In my opinion 6.77626e-021 is very accurate.
6.77626e-021 = 0.00000000000000000000677626
Apr 1, 2013 at 8:07am UTC
It should be 0. Therefore 1 root. Your program tell that there is 2 roots. They look identical because only 6 digits are accounted, but there could be situation where it icould be critical.
Main point: never use == to compare floating point variables .
Apr 1, 2013 at 8:08am UTC
Do I use greater than, or less than signs etc. ?
Apr 1, 2013 at 8:12am UTC
use absolute difference (abs(val1-val2) < EPSILON ) instead. Its a bit complicated since you can get false results for numbers like 0.0f and 0.0000001f because the end result of 0.0000001f gets truncated for a float. Arbitrarily choose an amount of precision you are comfortable with and use the >, < operators instead.
1 2 3 4 5 6 7 8 9 10 11 12
#include <math.h>
#define EPSILON 0.0001f
int main(){
bool equal = false ;
float a = 0.0f;
float b = 0.00001f;
equal = (bool )( absf( a - b ) < EPSILON ); //close enough small enough difference
return (int ) equal;
}
EDIT:
It boils down to how floating point numbers are represented in memory. In IEEE 754
a 32 bit floating point has 1 bit for a sign (positive/negative) 8 bits for exponent and 23 bits for a significand (mantissa). The mantissa contains both parts from the fractional part of the number
and the whole (0+positive integer) number part. The exponent simply specifies where in the mantissa the decimal point for the whole number and fractional part of the number begins (the line in the sand). So you can get false results for arbitrarily small values (between 0 and 1) or large values greater than 23 bits (depending upon the exponent).
Last edited on Apr 1, 2013 at 8:22am UTC
Apr 1, 2013 at 8:14am UTC
Try the values, up the top.
Apr 1, 2013 at 8:25am UTC
my last bit of advice, is try to organize your code into levels and more consistently. read this:
http://www.cplusplus.com/forum/lounge/95892/
you're doing better than most beginners in c++ since you can actually compile a working program. so keep building and reading.
Last edited on Apr 1, 2013 at 8:26am UTC
Apr 1, 2013 at 8:29am UTC
Thank you for the advice, although I do like my style.
As I write, in order what my program will do before I write the code (algorithm), I write the code in a logical way.
Apr 1, 2013 at 8:37am UTC
Just needs at least 1 enter after each statement imo, but thats just me. I think coding is a form of art, and how you code your style is reflective of your experience. In all it makes it easier for everyone to read your code when you code in not only a logical way but a stylistic way. Much like indenting, using commas, and breaking ideas into paragraphs makes an essay more readable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
//include headers
#include <iostream>
#include <stdio.h>
using namespace std;
//declare global constants/variables
static int g_counter = 0;
//declare prototype
void function();
//declare implementation
void function()
{
printf("to infinity and beyond: %d\n" , g_counter );
g_counter++;
}
//run program
int main()
{
//variables and instance data here
int a = 0;
int b = 0;
std::string str = "Hello World" ;
//routines here, seperated by 1 vertical whitespace
while (true )
{
//check condition if condition, call function
if ( 1 == 1 )
function(); //call function
std::cout << str << std::endl;
}
return 0; //return status
}
Last edited on Apr 1, 2013 at 8:42am UTC
Apr 1, 2013 at 8:43am UTC
0.00000000001 - works well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
int main()
{
string use_again;
string a_var_s;
long double a_var = 0;
string b_var_s;
long double b_var = 0;
string c_var_s;
long double c_var = 0;
long double b_var_sqrd = 0;
long double discriminant = 0;
unsigned int discriminant_indication = 0;
long double divisor = 0;
long double dividend = 0;
long double root_var = 0;
long double res = 0;
long double res_2 = 0;
string correct_equation;
string correct_equation_validation;
do {
cout << endl;
cout << "Quadratic equation calculator, 2.0." << endl;
cout << endl;
cout << "This program only calculates quadratic equations that are in ax^2 + bx + c = 0 form." << endl;
cout << endl;
cout << "This form is also known as standard form." << endl;
cout << endl;
while ( correct_equation != "y" )
{
cout << "Input the value of a:" << endl;
getline ( cin, a_var_s );
stringstream( a_var_s ) >> a_var;
cout << "Input the value of b:" << endl;
getline ( cin, b_var_s );
stringstream( b_var_s ) >> b_var;
cout << "Input the value of c:" << endl;
getline ( cin, c_var_s );
stringstream( c_var_s ) >> c_var;
cout << endl;
cout << "Did you mean to input the following equation: " << a_var << "x^2" ;
if ( b_var >= 0 )
cout << "+" << b_var << "x" ;
else
cout << b_var << "x" ;
if ( c_var >= 0 )
cout << "+" << c_var;
else
cout << c_var;
cout << " = 0?" << endl;
cout << endl;
do {
cout << "Input 'y' if the equation was correct." << endl;
cout << "Input 'n' if the equation was incorrect." << endl;
cin >> correct_equation;
if ( correct_equation != "y" && correct_equation != "n" )
{
correct_equation_validation = "n" ;
cout << "Invalid user input. Please try again." << endl;
cout << endl;
}
else if ( correct_equation == "y" )
correct_equation_validation = "y" ;
else
{
correct_equation_validation = "y" ;
correct_equation = "n" ;
}
cin.ignore();
} while ( correct_equation_validation == "n" );
}
b_var_sqrd = pow ( b_var, 2 );
discriminant = b_var_sqrd - 4*a_var*c_var;
cout << "The discriminant of the equation is " << discriminant << "." << endl;
cout << "Therefore: " ;
if ( discriminant >-0.00000000001 && discriminant < 0.00000000001 ) // Never use == to compare floating point variables.
{
cout << "x can only have one real value." << endl;
discriminant_indication = 1;
}
else if ( discriminant < 0 )
{
cout << "x has no real values." << endl;
discriminant_indication = 0;
}
else
{
cout << "x has two real values." << endl;
discriminant_indication = 2;
}
root_var = sqrt( discriminant );
dividend = -1 * b_var + root_var;
divisor = 2 * a_var;
res = dividend/divisor;
if ( discriminant_indication == 1 )
cout << "x = " << res << "." << endl;
else if ( discriminant_indication == 2 )
{
cout << "x = " << res << "." << endl;
dividend = -1 * b_var - root_var;
divisor = 2 * a_var;
res_2 = dividend/divisor;
cout << "OR: x = " << res_2 << "." << endl;
}
cout << "Input 'y' to use this program again:" << endl;
cin >> use_again;
correct_equation = "n" ;
cin.ignore();
} while ( use_again == "y" || use_again == "Y" );
cin.get();
return 0;
}
Last edited on Apr 1, 2013 at 8:47am UTC
Apr 1, 2013 at 8:46am UTC
it works because you are using doubles (double the precision of floats). If you tried that sort of precision with a float, it might not work :)
Apr 1, 2013 at 8:48am UTC
Float is less accurate than long double.