### Need constructive criticism for Quadratic equation calculator 2.0!

Pages: 12
Hello. I require constructive criticism for my new quadratic equation calculator, 2.0

Thank you.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122`` ``````#include #include #include #include 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
It won't work right in some cases:
 ```a = 0.1 b = 0.33 c = 0.27225```
If you solve this yourself, you will see that discriminant is 0.
 ```The discriminant of the equation is 6.77626e-021. Therefore: x has two real values.```
That happens because of rounding problems:
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
http://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values
http://floating-point-gui.de/errors/comparison/

Second: A good idea is to separate your program into several logically separated reusable parts.

EDIT:
This: http://en.cppreference.com/w/cpp/io/manip/showpos manipulator maybe of use for you.
Last edited on
MiiNiPaa,

How can I fix the rounding problems?
Also, I have been trying online quadratic equation calculators, that also calculate the discriminant, and even they calculate the incorrect discriminant.
Last edited on
I do not understand the links provided.
In my opinion 6.77626e-021 is very accurate.

6.77626e-021 = 0.00000000000000000000677626
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.
Do I use greater than, or less than signs etc. ?
Fixed.
 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122`` ``````#include #include #include #include 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; float res = 0; float 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 >-1 && discriminant < 2 ) { 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; }``````
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.

 ``123456789101112`` ``````#include #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
I have.
Try the values, up the top.
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
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.
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.

 ``12345678910111213141516171819202122232425262728293031323334353637383940`` ``````//include headers #include #include 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
I did.
0.00000000001 - works well.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122`` ``````#include #include #include #include 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
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 :)
Float is less accurate than long double.
Pages: 12