if-else statement behaving incorrectly - c++

So i have two functions. one function checks to see if the given sides form a right triangle. The problem is that when I call the function in the if-else statement in classify, I always get "Not a right Triangle" even though the value of isRightTriangle(sides) is true.
bool isRightTriangle(int sides[])
{
std::sort(sides, sides+3);
if((pow(sides[0],2) + pow(sides[1],2)) == pow(sides[2],2))
return true;
return false;
}
void classify(int sides[], ofstream &outfile)
{
int largest(int []);
void typeOfTriangle(int [], ofstream &);
bool isRightTriangle(int []);
outfile << "Largest Side: " << largest(sides) << endl;
typeOfTriangle(sides,outfile);
if(isRightTriangle(sides))
outfile << "Right Triangle\n\n\n";
else
outfile << "Not a Right Triangle\n\n\n";
}

Floating point arithmetic doesn't generally produce perfectly precise results, but == checks for exact equality. Instead of comparing a == b, use abs( a - b ) < precision_limit. This essentially applies to floating-point arithmetic in all languages.
This doesn't explain why it would fail for 3, 4, 5, but there appears to be a lot of code you're not showing us. It would be a very good idea to have isRightTriangle print the numbers it's analyzing before the if.
(By the way, now I see you're passing integers to pow. In this case, imprecise results can only occur for very large numbers, and the precision_limit would be at least one.)

As others have mentioned, you're using floating point values and expecting exact results. Since you're only ever squaring the numbers (pow(x, 2)) you should just multiply them together instead. That's usually faster than pow, even for floats, and it works for any type of number.

Related

Comparing double error C++

recently I bump into a problem while comparing a double in an if statement. I was trying to cout the number of whole numbers in a double. Being a beginner, I am not sure what gone wrong in my code.
This is my code:
#include <iostream>
using namespace std;
int main(){
int x=0;//convert double to int
long double Out;//Result
long double In=10;//Input double
//Loop Begin
while(In>0){
x=In;//convert double to int
Out= (x/In);//Out(test if whole number, will return 1)
//test for 1
////////////////
if(Out == 1 ){
cout<<"[Whole Number] ";
}
////////////////
//test end
cout<<"In :"<<In<<", ";
cout<<"X :"<<x<<", ";
cout<<"Out :"<<Out<<endl;
In-=0.1;//decrease to finish loop (eventually)
}
//Loop End
cin.get();
return 0;
}
This program will test and output the whole numbers in the double (In). I realized that the accuracy of the double was affecting the if statement which is why I can't get the "[Whole Number]" result. Although I found out that if I used (0.9999) in "if(Out >= 0.9999)" the comparison would work. But I am not sure of a solution, please help! Much appreciated!
Your while loop never stops , its a infinite loop . You are not doing anything with the value of "In" in the while loop hence it will always be greater than 0 ,therefore a infinite loop .
You should probably approach the problem more directly with modf:
double int_part, frac_part;
frac_part = std::modf(in, &int_part);
if (frac_part == 0) {
// int_part contains integer value.
} else {
// process the double non-integer floating point value.
}
Your code works perfectly fine. If you subtract 0.1 from 10.0, then chances are that the result is not an integer due to rounding errors, and your code tells you exactly that. The code isn't wrong, your expectations are wrong.
if (Out >= 0.9999)
is obviously not a solution, because it will always be true if In >= 10000.0.
Do to the way floating point numbers are converted to binary representation by the computer they are inherently inaccurate and thus make logical comparisons somewhat challenging (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems). When performing such comparisons to floating point numbers you typically will do so utilizing an epsilon constant (http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm) that represents the maximum acceptable error in the comparison. In your case you need to select a suitable value for epsilon (say .000001). Then change your comparison to:
if(abs(out - 1) < epsilon){ //Take the difference between out and 1
cout<<"[Whole Number]"; //If it is "close enough" print to console
}
I am more of a Java guy but I believe you will need #include stdlib.h to utilize the abs() function.
Hope that helps!
Try using the modulus operator: http://www.cprogramming.com/tutorial/modulus.html
Something like if(In % 1 == 0) should work.

Console outputting a certain value - if statement straight after it not working with same value

cout << levelData.interactMap[tileHitX][tileHitY] << endl;
if(levelData.interactMap[tileHitX][tileHitY] == 1.8)
cout << "pls werk" << endl;
So the cout outputs 1.8...yet the if statement does not work.
It's a function in which I'm passing a struct member to using the & pointer.
It's inside this if statement.
if(levelData.interactMap[tileHitX][tileHitY] >= 1 & levelData.interactMap[tileHitX][tileHitY] <= 1.8)
{
levelData.interactMap[tileHitX][tileHitY] = levelData.interactMap[tileHitX][tileHitY] + 0.1;
chop.play();
cout << levelData.interactMap[tileHitX][tileHitY] << endl;
if(levelData.interactMap[tileHitX][tileHitY] == 1.8)
cout << "pls werk" << endl;
}
Calling the function
int action(int facing, sf::Sprite& player, sf::View& view, sf::Clock& actionTimer, levelData& levelData, sf::Sound& chop)
and the define thing for the function
int action(int, sf::Sprite&, sf::View&, sf::Clock&, levelData&, sf::Sound&);
Thanks
As mentioned in several comments, floating point numbers are a little weird when it comes to equality. This is because, to use a reasonable amount of memory, floating point numbers are not stored exactly, but approximated using increasingly small powers of 2 (i.e. 2^-1 + 2^-2 + 2^-4....). As you might expect, this means that there is a margin of error involved, depending on several factors.
As far as your problem is concerned, it comes down to this: don't use "==" on floating point numbers. Instead, check to see if it is within a margin of error with something like:
float acceptableThresholdOfError = .0001;
if(fabs(levelData.interactMap[tileHitX][tileHitY] - 1.8) <= acceptableThresholdOfError)
{ //code }
Obviously, the needed precision determines exactly how small the error threshold should be/can be. This way, even if your variable is not a perfect approximation, it can be thought of as such as long as it's "close enough."

C++ simple If statement making the rest of the program not execute

I have an assignment where I must read from a file and perform various calculations on it and write the answer to an output file. Everything was going great until I came to this step:
"Reread the file and compute the sum of the integers in the file as long as the sum does not exceed 1000. Use a flag controlled loop structure."
My code snippet is as follows:
dataFile2.close();
dataFile2.clear();
dataFile2.open("J:\\datafile2.txt");
sum = 0;
while(sum < 1000)
{
dataFile2 >> num;
sum = sum + num;
if(sum > 1000)
sum = sum - num;
}
answers << "The sum of the integers not exceeding 1000 is " << sum << endl;
cout << "The sum of the integers not exceeding 1000 is " << sum << endl;
return 0;
My variables have already been declared. when I take out the if statement the sum adds the last number and the sum then exceeds 1000. When the If statement is left in, the answers and cout statements are not executed and there are no compiler warnings or errors.
Any help on this would be greatly appreciated.
-ThePoloHobo
Since no one seems to want to give you a correct answer... (and
to be fair, it's hard to give a correct answer without actually
doing your work for you).
There are two issues in you code. The first is the requirement
that you use a flag. As I said in my comment, the idiomatic
solution would not use a flag, but there's no problem using one.
A flag is a boolean variable which will be tested in the
while, and will be set in a conditional in the loop, when you
find something that makes you want to leave the loop.
The second issue is that you are using num without checking
that the input has succeeded. You must check after the >>
operator. The idiomatic way of checking (and the only thing
that should ever be used by someone not experienced in the
language) is to treat the stream as if it were a boolean:
dataFile2 >> num;
if ( dataFile2 ) {
// Input succeeded...
} else {
// Input failed for some reason, maybe end of file
}
Since all operations on a stream return a reference to the
stream, it is usual to merge the test and the input:
if ( dataFile2 >> num ) {
// succeeded
} else {
// failed
}
(Personally, I find the idea of modifying state in the condition
of an if or a while horrible. But this idiom is so
ubiquitous that you should probably use it, for the simple
reason that that's what everyone expects.)
In pedagogical environments, it's probably acceptable to
consider any failure to be end of file, and just move the test
up into the while (except, of course, that you've been asked
to use a flag). In other contexts, you'll want to take into
account the fact that the failure could be due to a syntax error
in the input—someone inserted "abc" into the file where
you were expecting a number. There are a number of ways of
handling this, all of which are beyond the scope of what you are
trying to do, but be aware that after you've detected failure,
you can interogate the stream to know why. In particular, if
dataFile2.eof() is true, then the failure was (probably) due
to you having read all of the data, and everything is fine. (In
other words, failure to read a data is not necessarily an error.
It can be simply end of file.)
You don't seem to be using a flag variable, which could help in this case. Something like this should fix it:
sum = 0;
bool sumUnder1000 = true; //Or the C++ equivalent, I'm a bit rusty
while(sumUnder1000)
{
if(!dataFile2.good()){
sumUnder1000 = false; //We've reached end of file or an error has occurred
return;
}
dataFile2 >> num;
sum = sum + num;
else if(sum > 1000){
sum = sum - num;
sumUnder1000 = false;
}
}

Check multiple OR operators in IF statement

I have the following C++ code:
if(x==y||m==n){
cout<<"Your message"<<endl;
}
If x is equal to y or m is equal to n, the program prints "Your message". But if both conditions are true,the program tests only one of them and eventually prints one "Your Message".
Is there a way to print each "Your message" independently based on each condition using a single if statement?
The output would be identical to the below using multiple if statements.
if(x==y){
cout<<"Your message"<<endl;
}
if (m==n){
cout<<"Your message"<<endl;
}
Not that I'd ever do it this way, but ...
for(int i = 0; i < (x==y)+(m==n); ++i) {
std::cout << "Your message\n";
}
Let me expand on this. I'd never do it this way because it violates two principles:
1) Code for maintainability. This loop is going to cause the maintainer to stop, think, and try to recover your original intent. A pair of if statements won't.
2) Distinct input should produce distinct output. This principle benefits the user and the programmer. Few things are more frustrating than running a test, getting valid output, and still not knowing which path the program took.
Given these two principles, here is how I would actually code it:
if(x==y) {
std::cout << "Your x-y message\n";
}
if(m==n) {
std::cout << "Your m-n message\n";
}
Aside: Never use endl when you mean \n. They produce semantically identical code, but endl can accidentally make your program go slower.
I don't think that's possible. What you have inside your bracket is a statement which is either true or false, there's no such thing like a true/true or true/false statement. What you could do is a do/while loop with a break statement. But I don't think that's the way to go. Why do you want to avoid two if statements?
single "|" or "&" gaurantees both side evaluation even if the result can be determined by left side operator alone.
You could do something like this, to build up the "message":
string msg = "Your Message\n";
string buildSt = x == y ? m == n ? msg + msg : msg : m == n ? msg : "";
Compiler checks only one condition when both are true because you've connected your conditions with OR.
If even one condition in ORs chain is true there is no need to check others as a result already true and will be false if one of them is false. So if you think that your logic is right then there is no need to do multiple checks. Your code is asking that you will print a message if one of the conditions is true and program doing it. If you want something special for a case when both conditions are true then add it separately. Shortly you should never expect from the compiler to do all checks in the expressions connected by OR.
Regards,
Davit
Tested code:
#include <iostream>
#include <string>
using namespace std;
void main() {
int x=1;
int y=1;
int m=1;
int n=1;
string mess1="Your message 1\n";
string mess2="Your message 2\n";
cout<<((x==y)?mess1:"")+((m==n)?mess2:"");
getchar();
}
If you are trying to see if both statements are true an && is what you will want to use.
Take a look at Boolean Operators to see all of the possible options when comparing boolean (true/false) values.
To answer your question:
if ((x==y) && (m==n))
{
cout<<"Your Message"<<endl<<"Your Message"<<endl;
}
else if((x==y) || (m==n))
{
cout<<"Your Message"<<endl;
}

Memoization Recursion C++

I was implementing a recursive function with memoization for speed ups. The point of the program is as follows:
I shuffle a deck of cards (with an equal number of red and black
cards) and start dealing them face up.
After any card you can say “stop”, at which point I pay you $1 for
every red card dealt and you pay me $1 for every black card dealt.
What is your optimal strategy, and how much would you pay to play
this game?
My recursive function is as follows:
double Game::Value_of_game(double number_of_red_cards, double number_of_black_cards)
{
double value, key;
if(number_of_red_cards == 0)
{
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), number_of_black_cards));
return number_of_black_cards;
}
else if(number_of_black_cards == 0)
{
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), 0));
return 0;
}
card_iter = Card_values.find(Key_hash_table(number_of_red_cards, number_of_black_cards));
if(card_iter != Card_values.end())
{
cout << endl << "Debug: [" << number_of_red_cards << ", " << number_of_black_cards << "] and value = " << card_iter->second << endl;
return card_iter->second;
}
else
{
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/number_of_total_cards;
prob_black_card = number_of_black_cards/number_of_total_cards;
value = max(((prob_red_card*Value_of_game(number_of_red_cards - 1, number_of_black_cards)) +
(prob_black_card*Value_of_game(number_of_red_cards, number_of_black_cards - 1))),
(number_of_black_cards - number_of_red_cards));
cout << "Check: value = " << value << endl;
Card_values.insert(Card_values.begin(), pair<double, double> (Key_hash_table(number_of_red_cards, number_of_black_cards), value));
card_iter = Card_values.find(Key_hash_table(number_of_red_cards , number_of_black_cards ));
if(card_iter != Card_values.end());
return card_iter->second;
}
}
double Game::Key_hash_table(double number_of_red_cards, double number_of_black_cards)
{
double key = number_of_red_cards + (number_of_black_cards*91);
return key;
}
The third if statement is the "memoization" part of the code, it stores all the necessary values. The values that are kept in the map can be thought of as a matrix, these values will correspond to a certain #red cards and #black cards. What is really werid is that when I execute the code for 8 cards in total (4 blacks and 4 reds), I get an incorrect answer. But when I execute the code for 10 cards, my answer is wrong, but now my answer for 4 blacks and 4 reds are correct (8 cards)! Same can be said for 12 cards, where I get the wrong answer for 12 cards, but the correct answer for 10 cards, so on and so forth. There is some bug in the code, however, I can't figure it out.
Nobody actually answered this question with an answer. So I will give it a try, though nneonneo actually put his or her finger on the likely source of your problem.
The first problem that's probably not actually a problem in this case, but sticks out like a sore thumb... you are using double to hold a value that you mostly treat as an integer. In this case, on most systems, this is probably OK. But as a general practice, it is very bad. In particular because you check if a double is exactly equal to 0. It probably will be as, on most systems, with most compilers, a double can hold integers values up to a fairly large size with perfect precision as long as you restrict yourself to adding, subtracting and multiplying by other integers or doubles masquerading as integers to get a new value.
But, that's likely not the source of the error you're seeing, it's just trips every good programmer's alarm bells for smelly code. It should be fixed. The only time you really need them to be doubles is when you're calculating the relative probability of red or black.
And that brings me to the thing that probably is your problem. You have these two statements in your code:
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/number_of_total_cards;
prob_black_card = number_of_black_cards/number_of_total_cards;
which, of course, should read:
number_of_total_cards = number_of_red_cards + number_of_black_cards;
prob_red_card = number_of_red_cards/double(number_of_total_cards);
prob_black_card = number_of_black_cards/double(number_of_total_cards);
because you've been a good programmer and declared those variables as integers.
Presumably prob_red_card and prob_black_card are variables of type double. But they are not declared anywhere in the code you show us. This means that no matter where they are declared, or what their types are, they must be effectively shared by all sub-calls in the recursive call tree for Game::Value_of_game.
The is almost certainly not what you want. It makes it extremely difficult to reason about what values those variables have and what those values represent during any given call in the recursive call tree for your function. They really have to be local variables in order for the algorithm to be tractable to analyze. Luckily, they seem to only be used within the else clause of a particular if statement. So they can be declared when they are initially assigned values. Here is probably what this code should read:
unsigned const int number_of_total_cards = number_of_red_cards + number_of_black_cards;
const double prob_red_card = number_of_red_cards/double(number_of_total_cards);
const double prob_black_card = number_of_black_cards/double(number_of_total_cards);
Note that I also declare them const. It is good practice to declare any variable who's value you don't expect to change during the lifetime of the variable as const. It helps you write code that is more correct by asking the compiler to tell you when you accidentally write code that is incorrect. It also can help the compiler generate better code, though in this case even a trivial analysis of the code reveals that they are not modified during their lifetimes and can be treated as const, so most decent optimizers will essentially put the const in for you for the purposes of code optimization, though that still will not give you the benefit of having the compiler tell you if you accidentally use them in a non-const way.