Hey there! About a week ago, I started working with C++, just as a hobby. I started working on a Square Root Calculator, just to use it as a reference for my future C++ projects. :)

However, when some of my friends were wondering that I could implement 'Pi' within my program, I figured I could give it a shot. So I wrote in 4 const doubles about the 4 variations of Pi:

const double pi = 3.1415926535;
const double Pi = 3.1415926535;
const double pI = 3.1415926535;
const double PI = 3.1415926535;

however, because of it counteracting with another error, that only numbers can be typed in, from 0-9, such as this:

for (int i = 0; i < number.length(); ++i) // Loop that goes through all the letters
{
if (number[i] != '.' && number[i] < '0' || '9' < number[i] || number[0] == 'p' && number[1] == 'i') // Does the character have a value under 0 or above 9, a demical or 'Pi'?
{
cout << "\nERROR: " << "'" << number << "'" << " is not a number.\n";
main();
}
if(number[i] == '.')
{
dotsomg++;
}
}
if(number[0] == 'p' && number[1] == 'i')
{
number[i] == 'pi';
}

I know the code is defiantly wrong, but this is what I'm stuck at so far. The old code that I thought would work better would be this:

for (int i = 0; i < number.length(); ++i) // Loop that goes through all the letters
{
if (number[i] != '.' && number[i] < '0' || '9' < number[i] || number[i] == 'pi' || number[i] == 'PI' || number[i] == 'pI' || number[i] == 'Pi') // Does the character have a value under 0 or above 9, a demical or 'Pi'?
{
cout << "\nERROR: " << "'" << number << "'" << " is not a number.\n";
main();
}
if(number[i] == '.')
{
dotsomg++;
}
}
if(number[i] = pi || number[i] == PI || number[i] == Pi || number[i] == pI)
{
number[i] = pi;
}

EDIT: The "number" was only for testing, but I doubt that it is still correct though. =/

However, both codes no not work, and I am stumped. If you guys want me to post the entire code, then np, if not, then I'll try and discuss this more in depth.

I tried to make this post as understanding to the best of my ability, but I do have a slight speech impediment, so forgive me if I don't make sense in some parts...

Take care for now. :)

What the heck? Why did you do this?

const double pi = 3.1415926535;
const double Pi = 3.1415926535;
const double pI = 3.1415926535;
const double PI = 3.1415926535;

What were you trying to accomplish?

>What were you trying to accomplish?
The need for case-sensitive variables :P

What the heck? Why did you do this?

const double pi = 3.1415926535;
const double Pi = 3.1415926535;
const double pI = 3.1415926535;
const double PI = 3.1415926535;

What were you trying to accomplish?

I'm tryign to impliment Pi within my code, but I'm trying to oversee an error that the number that only numbers can eb typed in, to prevent a glitch. Also, case sensitive variables.

Edit: William beat me to it. :P

If I'm doing something incredibly stupid, plz don't hesitate to tell me now, I probably deserve it. xD

Would you like em to post my entire code, if that would be better? :)

Also, your last if statement in your snippet will always be true, you only used one =

>If I'm doing something incredibly stupid
The truth is, you are doing lots of incredibly stupid things :P but that's normal for newbs, don't worry about it.

I'm not even going to bother trying to understand that code, but it's full of small bugs such as this:

if(number[i] [B]=[/B] pi || number[i] == PI || number[i] == Pi || number[i] == pI)

Not to mention the entire line is pointless anyway.

My advice for you is to start over, read a tutorial or book on C++, and scrap this code.

main();

Calling main recursively isn't allowed in C++. It's a bad practice even if your compiler allows it. ;)

What were you trying to accomplish?

I think it's an input parsing algorithm that looks for fixed point values or variations of PI. The fixed point value is checked and if it's PI, the string is replaced with the value of PI. Something like this:

if (IsValidFixed(number)) continue;
else if (UpperCase(number) == "PI") number = PI;
else
{
Panic("Not a valid number");
}

Also, your last if statement in your snippet will always be true, you only used one =

Hmm...ah yes, I was just trying out three different techniques, and I forgot to put back in the "==" instead of "=", but even then when I tried a while back with "==", it still errored on me. :S

Edit: Ah ok, I'll see if I can try and reset the thing then, probably needs it anyway. :)

Pardon my double post, I know you guys probably don't appreciate it, but I figure I'll show you my entire code, maybe you can help em further in depth (if possible), otherwise it's getting a reset. :) And tbh, a reset would probably be best, but it probably won't hurt to see the entire thing. :)

#include <iostream>
#include <cmath>
#include <windows.h>
#include <stdio.h>
#include <sstream>
#include <iomanip>

using namespace std;

namespace jrd // Allow the exact precision to rise for the decimal place to be different than 6 units
{
int digits(double val)
{
ostringstream oss;
oss << static_cast<int>(val);
return oss.str().length();
}
}

int main() // Calculating part
{
SetConsoleTitle("RoninMastaFX's Square Root Calculator v0.9.2 BETA 3.5"); // Title of Application
double x = 2.3767553235;
cout.precision(10 + jrd::digits(x)); // Increases the demical units from 6 to 10 for better rounding of the output number
double num1;
const double pi = 3.1415926535; // These four const doubles are verifying 'Pi'
const double Pi = 3.1415926535;
const double pI = 3.1415926535;
const double PI = 3.1415926535;
string number; // Declares string
int dotsomg = 0;
cout << "Enter your number..." << endl;
getline(cin, number); // Inputs number

//
// Alright, this is where the 'debugging' code is so that this program won't be fucked around with while in use
//

if(number.length() < 1)
{
cout << "\nERROR:  You have not entered anything.\n";
main();
}
if(number.length() == 1 && number[0] == '.')
{
cout << "\nERROR: A decimal by itself is not allowed.\n";
main();
}
for (int i = 0; i < number.length(); ++i) // Loop that goes through all the letters
{
if (number[i] != '.' && number[i] < '0' || '9' < number[i] || number == 'pi' || number == 'PI' || number == 'pI' || number == 'Pi') // Does the character have a value under 0 or above 9, a demical or 'Pi'?
{
cout << "\nERROR: " << "'" << number << "'" << " is not a number.\n";
main();
}
if(number[i] == '.')
{
dotsomg++;
}
}
if(number == pi || number == PI || number == Pi || number == pI)
{
number == pi;
}

if(number[0] == '0' &&  number[1] != '.')
{
cout << "\nERROR: You cannot have zeros by themselves.\n";
main();
}
if(number[1] == '.' && number[2] < '1' && number.length() < 3 || number[1] == '.' && number[2] > '9')
{
cout << "\nERROR: You have entered an invalid number scheme.\n";
main();
}
if(dotsomg > 1)
{
cout << "\nERROR: You have entered too many decimals.\n";
main();
}

//
// Debugging code finished
//

istringstream cin (number);
cin >> num1;
double num2;
num2 = sqrt(num1);
cout << "\nThe square root of " << num1 << " is:\n";
cout << num2 << " - exact (10) units\n";
printf("%.8f - 8 units\n",num2);
printf("%f - 6 units\n",num2);
printf("%.4f - 4 units\n",num2);
printf("%.2f - 2 units\n",num2);
printf("%.0f - whole number\n",num2);
}

{
string yesno;
cout << "\nWould you like to make another equation?\n";
getline(cin, yesno);
if(yesno[0] == 'y')
{
cout << "\n";
main();
}
else if(yesno[0] == 'Y')
{
cout << "\n";
main();
}
else if(yesno[0] == 'n')
{
exit (1);
}
else if(yesno[0] == 'N')
{
exit (1);
}
else
{
cout << "\nERROR: " << "'" << yesno << "'" << " is not a valid answer.\nPlease type Yes to continue or No to exit.\n";
}
return 0;
}

Also, the code is not neat, yet. I am a perfectionist, but once the bugs are all gone, and then I tidy up the code and make it sparkle. :P

It seems indeed that is what he is trying to accomplish.

However, RoninMastaFX when you think about this problem logically, there must be a better way than defining variables with all possible case-variations.

What I think you have in mind is this:
A user types in the string "pi" (or any of its case variation) and you 'replace' it with the variable pi (or any if its case variation). But this will never work out, you can't say the following:

const double pi = 3.1415926535;
string myString = "pi";
double myResult = 3*myString;

I think that is essentially what you are trying to do.

What you can do is comparing the input from the user with the string "pi" and then saying 'ok, we need to replace pi somewhere'

const double pi = 3.1415926535;
string myString = "pi";  // This is the user's input
if( myString == "pi" )
{
[indent]doublemyResult = 3 * pi;[/indent]
}

To avoid comparing myString with "pi", "Pi" and all other case variations you should decide to either make the users input string all lower-case and compare to "pi" or all upper case and compare to "PI" (be consistent in this).

I havn't looked exactly at your piece of code but that is the idea I got from your explanation, I hope it makes sense to you and that you can get further with it.

I just saw that you've pasted the entire code and I noticed this:

if(number == pi || number == PI || number == Pi || number == pI)
{
[indent]number == pi;[/indent]
}

I'm not trying to be offensive, but the logic of this is pretty hard to find.
You are essentially comparing number to either one of the case-variation constants that you defined, and if number matches to either one of them, you assign number to the value of pi (you've used double = here which means you are actually comparing number to pi again but I assume you mean to assign the value of pi to number)
That piece of code will not get you any further

@thelamb I don't find that post offensive one bit. :) I'm just trying to get help on what I'm doing wrong with Pi and how I can fix it, nothing more, nothing less. ;)

I also completely understand what you explained to me, and I'll see what I can do using your advice. :)

This should help give you ideas for how it can be done without all of that extra work and buggy loops:

#include <algorithm>
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>

using namespace std;

namespace
{
const double PI = 3.14159;
}

bool IsValidFixed(string s)
{
int dots;

// check that only digits and dots are present
// check that only 1 or 0 dots are present
return s.find_first_not_of(".0123456789") == string::npos &&
((dots = count(s.begin(), s.end(), '.')) == 0 || dots == 1);
}

string UpperCase(const string& s)
{
string temp;

for (string::size_type x = 0; x < s.length(); ++x)
{
temp += toupper(s[x]);
}

return temp;
}

int main()
{
string number;

while (getline(cin, number))
{
if (IsValidFixed(number)) cout << atof(number.c_str()) <<'\n';
else if (UpperCase(number) == "PI") cout << PI << '\n';
else cerr << "Not a valid number\n";
}
}

It's important to see that the name of a macro isn't the same as the string you're parsing. You only need one PI. ;) The casing problem is with the input string, and that can be fixed by forcing all of the characters to a single case.

I'm not even going to bother trying to understand that code, but it's full of small bugs such as this:

if(number[i] [B]=[/B] pi || number[i] == PI || number[i] == Pi || number[i] == pI)

Not to mention the entire line is pointless anyway.

My advice for you is to start over, read a tutorial or book on C++, and scrap this code.

Agreed, but one thing has definitely to be pointed out: never use floating point comparisons in your program, never!
(you might want to check this)

And instead of including stdio.h, you should include cstdio (the new-style header): #include <cstdio> :)

>>never use floating point comparisons in your program, never!

I agree with the sentiment, but the stridency is a bit much for my taste. True, other programming languages may deal with floating point values more elegantly that C/C++, but without comparing floating points there are lots of things we couldn't do. However, there are appropriate and inappropriate ways to do things. Using the equals operator to compare floating point numbers should be avoided, but then some other approach to determine "equality" needs to be devised. If the OP is interested in a detailed discussion of why this is so, then I'm sure someone will post an elegant discussion or post a reference link, otherwise, "close enough" is probably a better approach than iron clad equality. That is, take two floats and subtract them. Look at the difference. If the difference is less than a given predetermined value, then the floats are "close enough" and they will be considered equal, etc. Similarly for >, < , etc. Obviously, this introduces a degree of error with every calculation that needs to be done, so the more precise the calculations need to be, the smaller the difference needs to be.

^ what he's saying is that you should *never* use the "equal to" comparison operator for floating point variables.

while his vocabulary wasn't precise about the type of comparison operator, he's correct that you should never use the "equal to" comparison operator to compare floating points.

instead use the greater than and less than comparisons (as you mentioned) to effect an equivalant comparison within a specified tolerance.

.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.