Thread: Problem with simple IF

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    26

    Problem with simple IF

    for some reason, this doesn't work, and I can't figure out why.

    I'm probaby missing something easy, but here it is.. this is only part of the code I am testing, because it passes every time no matter what I put it..

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
     		double minutes, total, rate, num, num2;
    		cout << "Enter time call was started in HH.MM format\n\n\n";
    		cout << "Example: 07.51 is 7:51 \n\n";
    		cout << "Time: ";
    		
    		cin >> fixed >> setprecision(2) >> showpoint;
    		cin >> num;
    		cout << fixed << setprecision(2) << showpoint;
    		num2 = num - static_cast<int>(num); //should give the fractional part
    		cout << endl;
    		cout << num2;
    		cout << endl;
    		if (num2 < 0.6)
    	  	 cout << "\nok, this worked.\n";
      	else
    	  		cout << "ok, this didn't work.\n";

    thanks for any advice.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What input are you giving? What output are you getting? What output are you expecting?

    BTW, this appeared to work for me.

  3. #3
    village skeptic
    Join Date
    Aug 2008
    Posts
    31
    It worked for me as well. Of course, your output is wonky if you enter a value that doesn't have a fractional part to it...

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    what's your input? what's the output? what's the expected output?

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm also a bit confused as to what you are wanting to happen vs. what actually happens.

    I ran it with two different inputs, and it gives the expected result from what I read from the code itself - but I don't know what YOU EXPECT it to do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Jul 2008
    Posts
    26
    Quote Originally Posted by matsp View Post
    I'm also a bit confused as to what you are wanting to happen vs. what actually happens.

    I ran it with two different inputs, and it gives the expected result from what I read from the code itself - but I don't know what YOU EXPECT it to do.

    --
    Mats
    This is just part of a small program in my college book.

    The goal is to make a program, in which you enter a time and an amount of time, and calculate the results based on what rate the time you entered is at. So, if you start your call at 7:00 at night, the rate is .55 cents, if you start after 12:00am the rate is .22 cents (hypothetical).

    So, you have to make sure that noone enters a number > 23.59 (23:59), or < 0. Also, none of the decimal parts can be over .59. So, you can't enter 12.6 because thats not a valid time, but 12.59 is perfectly valid.

    That little part is just testing that you can find the last two digits of a Float by subtracting the number from itself with a static_cast<int> in the mix.

    When I run this, it always comes out true no matter what I enter. If I enter 12.59 it doesn't work either.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    12.59 is supposed to come out ok because 0.59 is less than 0.6.

    Can you be more specific?

  8. #8
    Registered User
    Join Date
    Jul 2008
    Posts
    26
    Quote Originally Posted by Daved View Post
    12.59 is supposed to come out ok because 0.59 is less than 0.6.

    Can you be more specific?
    Well, I think I got it figured out, but still not sure why it's having trouble knowing that .59 is < .6

    Specifically, you have it right.

    .59 is ok, .6 is not
    1.59 is ok, 1.6 is not,
    2.59 is ok, 2.6 is not

    .59 - .99 are not ok
    1.59 - 1.99 are not ok
    2.59 - 2.99 are not ok

    Do you see where I'm going. Just like you can't say "Hey the time is twelve sixty five!" because there is no such thing as twelve sixty five when you are dealing with time, therefore a person cannot enter 12.65 into this program.

    So, sometimes I enter 1.6 and it says it's ok, sometimes it says it's bad. (or 12.6 or 20.6 or 2.6, doesn't matter..) I just can't have it say that anything above .59 is ok.

    I ended up putting if (num < .6 && num != .6) and it seemed to work, even though it's redundant.

    Maybe it's because I'm using a free compiler.. (Dev c++)

    I hope that helps.

  9. #9
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    So, sometimes I enter 1.6 and it says it's ok, sometimes it says it's bad.
    Without reading your code, I am guessing it's because floating point numbers don't have infinite precision. Not all floating point numbers can be represented with infinite precision, so when you type in 2.6, it's possible that 2.60000001 or 2.599999999 is stored instead.

    You will have to do something like this:
    Code:
    const int EPSILON = 0.000001; /* a small number. error threshold */
    ...
    if (num < (0.6-EPSILON)) {
    ...
    }
    I ended up putting if (num < .6 && num != .6) and it seemed to work, even though it's redundant.
    It is indeed redundant, and I doubt it is actually what fixes your problem.

    Nothing wrong with the compiler. Free software does not have to be inferior to commercial software. The compiler that Dev-C++ uses, GCC, is a state of art compiler, not any worse than commercial compilers.

  10. #10
    village skeptic
    Join Date
    Aug 2008
    Posts
    31
    you do perform an operation where you are mixing variable types. could that be the cause of precision loss?

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I hope that helps. <<
    It shouldn't be too hard to give the exact input that isn't working for you, the exact output you get, and the exact output you expect.

    >> So, sometimes I enter 1.6 and it says it's ok, sometimes it says it's bad. (or 12.6 or 20.6 or 2.6, doesn't matter..) <<
    If you're testing exactly against something with a .6, then your problem is likely what cyberfish stated. See http://www.parashift.com/c++-faq-lit...html#faq-29.16 and 29.17 for more information.

  12. #12
    Registered User
    Join Date
    Jul 2008
    Posts
    26

    Minute numbers

    Quote Originally Posted by cyberfish View Post
    Without reading your code, I am guessing it's because floating point numbers don't have infinite precision. Not all floating point numbers can be represented with infinite precision, so when you type in 2.6, it's possible that 2.60000001 or 2.599999999 is stored instead.

    You will have to do something like this:
    Code:
    const int EPSILON = 0.000001; /* a small number. error threshold */
    ...
    if (num < (0.6-EPSILON)) {
    ...
    }

    It is indeed redundant, and I doubt it is actually what fixes your problem.

    Nothing wrong with the compiler. Free software does not have to be inferior to commercial software. The compiler that Dev-C++ uses, GCC, is a state of art compiler, not any worse than commercial compilers.
    Thats right, but I thought the "cin >> setprecision(2)" would take care of that? I need to look at my first message and see if I forgot to include that for the 'cin' statement.

    I'm going to dink around with your suggestion and see what I can make happen.

    thank you!


    Thanks!

  13. #13
    Registered User
    Join Date
    Jul 2008
    Posts
    26

    Good article.

    Quote Originally Posted by Daved View Post
    >> I hope that helps. <<
    It shouldn't be too hard to give the exact input that isn't working for you, the exact output you get, and the exact output you expect.

    >> So, sometimes I enter 1.6 and it says it's ok, sometimes it says it's bad. (or 12.6 or 20.6 or 2.6, doesn't matter..) <<
    If you're testing exactly against something with a .6, then your problem is likely what cyberfish stated. See http://www.parashift.com/c++-faq-lit...html#faq-29.16 and 29.17 for more information.
    Well, I'm sure when I get past chapter 4 of my book, it'll talk more about floats. It has mentioned that you cannot use == to compare floating point numbers or doubles, and a few other things, but nothing real complicated yet.

    Anyways, thats a good article, and definatly something to keep in memory.

    thanks.

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    IMHO, it is wrong to be reading a time into a double in this way. It isn't stored in any useful way. You can't add 0.30 to advance by half an hour properly, for example. It should be read in as two seperate integers instead, using a colon to seperate the hours and minutes, which is more logical anyway.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Registered User
    Join Date
    Aug 2008
    Posts
    2
    Quote Originally Posted by Zzaacchh View Post
    for some reason, this doesn't work, and I can't figure out why.

    I'm probaby missing something easy, but here it is.. this is only part of the code I am testing, because it passes every time no matter what I put it..

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
     		double minutes, total, rate, num, num2;
    		cout << "Enter time call was started in HH.MM format\n\n\n";
    		cout << "Example: 07.51 is 7:51 \n\n";
    		cout << "Time: ";
    		
    		cin >> fixed >> setprecision(2) >> showpoint;
    		cin >> num;
    		cout << fixed << setprecision(2) << showpoint;
    		num2 = num - static_cast<int>(num); //should give the fractional part
    		cout << endl;
    		cout << num2;
    		cout << endl;
    		if (num2 < 0.6)
    	  	 cout << "\nok, this worked.\n";
      	else
    	  		cout << "ok, this didn't work.\n";

    thanks for any advice.
    im no pro but you missed the { } on your if and else try this

    Code:
    if (num2 < 0.6){
    	  	 cout << "\nok, this worked.\n";
    }
      	else {
    	  		cout << "ok, this didn't work.\n";
    }
    hope it helps

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A simple file I/O problem
    By eecoder in forum C Programming
    Replies: 10
    Last Post: 10-16-2010, 11:00 PM
  2. Problem in simple code.
    By richdb in forum C Programming
    Replies: 6
    Last Post: 03-20-2006, 02:45 AM
  3. Problem in very simple code
    By richdb in forum C Programming
    Replies: 22
    Last Post: 01-14-2006, 09:10 PM
  4. Simple Initialization Problem
    By PsyK in forum C++ Programming
    Replies: 7
    Last Post: 04-30-2004, 07:37 PM
  5. Simple OO Problem
    By bstempi in forum C++ Programming
    Replies: 1
    Last Post: 04-30-2004, 05:33 PM