C++ if statements - only last one is ever true

Discussion in 'C++' started by root, Jan 4, 2004.

  1. root

    root Guest

    Hi group,

    Apologies in advance if this has been asked somewhere before, but I haven't
    managed to get anything from the Google archives - I've been getting
    introductory guides to C++ all day long.

    I am writing a program in Visual C++ 6 SP5.
    My code has a lot of "if" statements - 19 to be exact.
    If the if statements are true (technically, there should only be one that is
    ever true), the program needs to continue on after the if statements.
    Each if statement assigns a particular string value to a character/string
    array if the if statement is true.

    Unfortunately, I have the problem whereby only my 19th if statement is ever
    true. The rest never become true no matter what changes I make to my
    variables.

    I know using one big "switch" would be appropriate here, but is it possible
    to use switch with a float as its condition? My Visual C++ compiler didn't
    like it when I used that.

    Apologies for so many questions... any help would be appreciated.

    Thanks!
    root, Jan 4, 2004
    #1
    1. Advertising

  2. root

    Clark Cox Guest

    In article <bt7mk1$42ibn$-berlin.de>,
    "root" <> wrote:

    > Hi group,
    >
    > Apologies in advance if this has been asked somewhere before, but I haven't
    > managed to get anything from the Google archives - I've been getting
    > introductory guides to C++ all day long.
    >
    > I am writing a program in Visual C++ 6 SP5.
    > My code has a lot of "if" statements - 19 to be exact.
    > If the if statements are true (technically, there should only be one that is
    > ever true), the program needs to continue on after the if statements.
    > Each if statement assigns a particular string value to a character/string
    > array if the if statement is true.
    >
    > Unfortunately, I have the problem whereby only my 19th if statement is ever
    > true. The rest never become true no matter what changes I make to my
    > variables.
    >
    > I know using one big "switch" would be appropriate here, but is it possible
    > to use switch with a float as its condition? My Visual C++ compiler didn't
    > like it when I used that.
    >
    > Apologies for so many questions... any help would be appreciated.
    >
    > Thanks!
    >
    >


    Although I can't be sure, as your were rather vague about what the
    conditions these if statements are checking for are, it sounds to me
    like you're trying to test floating point values for equality, which is
    a big no-no. Check out:

    http://www.parashift.com/c -faq-lite/newbie.html#faq-29.17
    Clark Cox, Jan 4, 2004
    #2
    1. Advertising

  3. root

    John Carson Guest

    "root" <> wrote in message
    news:bt7mk1$42ibn$-berlin.de
    > Hi group,
    >
    > Apologies in advance if this has been asked somewhere before, but I
    > haven't managed to get anything from the Google archives - I've been
    > getting introductory guides to C++ all day long.
    >
    > I am writing a program in Visual C++ 6 SP5.
    > My code has a lot of "if" statements - 19 to be exact.
    > If the if statements are true (technically, there should only be one
    > that is ever true), the program needs to continue on after the if
    > statements.
    > Each if statement assigns a particular string value to a
    > character/string array if the if statement is true.
    >
    > Unfortunately, I have the problem whereby only my 19th if statement
    > is ever true. The rest never become true no matter what changes I
    > make to my variables.
    >


    You obviously have a bug in your code.

    > I know using one big "switch" would be appropriate here, but is it
    > possible to use switch with a float as its condition?


    No it isn't.

    Post your code (in compileable form) and people here will

    1. Find the bug.
    2. Possibly suggest a more elegant solution.


    --
    John Carson
    1. To reply to email address, remove donald
    2. Don't reply to email address (post here instead)
    John Carson, Jan 4, 2004
    #3
  4. root

    Christof Guest

    root wrote:

    > Hi group,
    >
    > Apologies in advance if this has been asked somewhere before, but I haven't
    > managed to get anything from the Google archives - I've been getting
    > introductory guides to C++ all day long.
    >
    > I am writing a program in Visual C++ 6 SP5.
    > My code has a lot of "if" statements - 19 to be exact.
    > If the if statements are true (technically, there should only be one that is
    > ever true), the program needs to continue on after the if statements.
    > Each if statement assigns a particular string value to a character/string
    > array if the if statement is true.
    >
    > Unfortunately, I have the problem whereby only my 19th if statement is ever
    > true. The rest never become true no matter what changes I make to my
    > variables.
    >
    > I know using one big "switch" would be appropriate here, but is it possible
    > to use switch with a float as its condition? My Visual C++ compiler didn't
    > like it when I used that.
    >
    > Apologies for so many questions... any help would be appreciated.
    >
    > Thanks!
    >
    >

    Hello nameless poster,

    we can't help you without seeing your code, so please try to minimize
    the problem and post your code here.

    --
    Regards,
    Christof Krueger
    Christof, Jan 4, 2004
    #4
  5. root

    root Guest

    Re: C++ if statements - only last one is ever true (code)

    "root" <> wrote in message
    news:bt7mk1$42ibn$-berlin.de...

    Thanks for all your replies so far.

    I can't post the entire block of code here for commercial reasons, but a
    selection of the if statements are:

    if(difference == 0.000) {
    strcpy(PFM_Date,"A5"); }

    if(difference == 0.052 || 0.053) {
    strcpy(PFM_Date,"M25"); }

    if(difference == 0.894 || 0.895) {
    strcpy(PFM_Date,"M29"); }

    if(difference == 0.947 || 0.948) {
    strcpy(PFM_Date,"A17"); }

    where:

    difference is of type float
    and PFM_Date[4] of type char.

    I am trying to set PFM_Date to a three-letter code if the conditions I've
    posted have been met. Only one of these many if statements will ever be
    true. My source file is of type .cpp in VC++ 6, SP5.

    TIA.
    root, Jan 4, 2004
    #5
  6. Re: C++ if statements - only last one is ever true (code)

    root wrote:

    > "root" <> wrote in message
    > news:bt7mk1$42ibn$-berlin.de...
    >
    > Thanks for all your replies so far.
    >
    > I can't post the entire block of code here for commercial reasons, but a
    > selection of the if statements are:
    >
    > if(difference == 0.000) {
    > strcpy(PFM_Date,"A5"); }
    >
    > if(difference == 0.052 || 0.053) {
    > strcpy(PFM_Date,"M25"); }
    >
    > if(difference == 0.894 || 0.895) {
    > strcpy(PFM_Date,"M29"); }
    >
    > if(difference == 0.947 || 0.948) {
    > strcpy(PFM_Date,"A17"); }

    What you are doing here is the following:

    if ( (difference == 0.947) || (0.948) ) {
    strcpy(PFM_Date,"A17"); }

    That means that your if-condition is true when either (difference ==
    0.947) is true, or if (0.948) is true. In C++ numeric values that are
    not 0 _always_ return true.
    In your posted code the last three strcpy-statements are executed, but
    you only see the effect of the last one, because it overwrites the
    contents of PFM_Date.
    What you probably mean is

    if ( (difference == 0.947) || (difference == 0.948) ) {
    strcpy(PFM_Date,"A17"); }


    Another _very_ important point: Never check float values for equality.
    There is no exact binary representation for the number 0.01 for example.
    So you should rather use if-statements in the following form:

    if ( (difference >= 0.947) || (difference < 0.948) ) {
    strcpy(PFM_Date,"A17"); }

    And even this can lead to wrong results because of rounding.

    --
    Regards,
    Christof Krueger
    Christof Krueger, Jan 4, 2004
    #6
  7. root

    david m- Guest

    Re: C++ if statements - only last one is ever true (code)

    Not convinced that any of the sample given evaluate to true!

    However,

    if (difference == 0.947 || 0.948)

    == has a higher precedence than || so the expression is

    (difference == 0.947) || 0.948

    the equality operator returns true of false
    the boolean OR operator || returns true or false.

    What you are presumably trying to type is

    (difference == 0.947) || (difference == 0.948)

    but I'd be very careful of testing floating point values in this way.

    Would something like

    (difference >= 0.947) && (difference <= 0.948)

    suffice?

    davd m.

    "root" <> wrote in message
    news:bt9idh$4b0l2$-berlin.de...
    > "root" <> wrote in message
    > news:bt7mk1$42ibn$-berlin.de...
    >
    > Thanks for all your replies so far.
    >
    > I can't post the entire block of code here for commercial reasons, but a
    > selection of the if statements are:
    >
    > if(difference == 0.000) {
    > strcpy(PFM_Date,"A5"); }
    >
    > if(difference == 0.052 || 0.053) {
    > strcpy(PFM_Date,"M25"); }
    >
    > if(difference == 0.894 || 0.895) {
    > strcpy(PFM_Date,"M29"); }
    >
    > if(difference == 0.947 || 0.948) {
    > strcpy(PFM_Date,"A17"); }
    >
    > where:
    >
    > difference is of type float
    > and PFM_Date[4] of type char.
    >
    > I am trying to set PFM_Date to a three-letter code if the conditions I've
    > posted have been met. Only one of these many if statements will ever be
    > true. My source file is of type .cpp in VC++ 6, SP5.
    >
    > TIA.
    >
    >
    david m-, Jan 4, 2004
    #7
  8. root

    root Guest

    Re: C++ if statements - only last one is ever true (code)

    "Christof Krueger" <> wrote in message
    news:bt9j4m$dvq$07$-online.com...
    > root wrote:
    >
    > > "root" <> wrote in message
    > > news:bt7mk1$42ibn$-berlin.de...

    > That means that your if-condition is true when either (difference ==
    > 0.947) is true, or if (0.948) is true. In C++ numeric values that are
    > not 0 _always_ return true.
    > In your posted code the last three strcpy-statements are executed, but
    > you only see the effect of the last one, because it overwrites the
    > contents of PFM_Date.
    > What you probably mean is
    >
    > if ( (difference == 0.947) || (difference == 0.948) ) {
    > strcpy(PFM_Date,"A17"); }


    Thanks for that. I've tried it and now PFM_Date is coming out as blank
    (it's being printed using a printf).

    > Another _very_ important point: Never check float values for equality.
    > There is no exact binary representation for the number 0.01 for example.
    > So you should rather use if-statements in the following form:
    >
    > if ( (difference >= 0.947) || (difference < 0.948) ) {
    > strcpy(PFM_Date,"A17"); }
    >
    > And even this can lead to wrong results because of rounding.


    I know this is really bad programming, but I must check for those specific
    values. Maybe C++ isn't the best language for this.

    Thanks again anyway.
    root, Jan 4, 2004
    #8
  9. Re: C++ if statements - only last one is ever true (code)

    root wrote:

    > "Christof Krueger" <> wrote in message
    > news:bt9j4m$dvq$07$-online.com...
    >
    >>root wrote:
    >>
    >>
    >>>"root" <> wrote in message
    >>>news:bt7mk1$42ibn$-berlin.de...

    >>
    >>That means that your if-condition is true when either (difference ==
    >>0.947) is true, or if (0.948) is true. In C++ numeric values that are
    >>not 0 _always_ return true.
    >>In your posted code the last three strcpy-statements are executed, but
    >>you only see the effect of the last one, because it overwrites the
    >>contents of PFM_Date.
    >>What you probably mean is
    >>
    >> if ( (difference == 0.947) || (difference == 0.948) ) {
    >> strcpy(PFM_Date,"A17"); }

    >
    >
    > Thanks for that. I've tried it and now PFM_Date is coming out as blank
    > (it's being printed using a printf).

    It's blank because none of the if-statements ever are true (I assume
    because you test float numbers for equality).
    Do you really want to test for the *exact* value 0.947 or the *exact*
    value 0.948? Should the test fail for 0.9475? Or for 0.94700001? And
    what's with 0.94699999?



    --
    Regards,
    Christof Krueger
    Christof Krueger, Jan 4, 2004
    #9
  10. root

    Paul Guest

    Re: C++ if statements - only last one is ever true (code)

    "root" <> wrote in message
    news:bt9k3o$4o97p$-berlin.de...
    > I know this is really bad programming, but I must check for those specific
    > values. Maybe C++ isn't the best language for this.
    >

    Checking for exact floating point values is not only bad programming in C++,
    it's bad programming in most other languages. Try the same thing with
    Fortran, C, BASIC, Pascal -- you'll get the same problems.

    What you need is to either use a library that gives you more precision
    (usually these libraries are used for business calculations, where exact
    arithmetic is mandatory), or use a language that has exact representation of
    such numbers. Maybe COBOL.

    Paul
    Paul, Jan 4, 2004
    #10
  11. Re: C++ if statements - only last one is ever true (code)

    On Sun, 04 Jan 2004 17:27:39 +0000, root wrote:

    > "root" <> wrote in message
    > news:bt7mk1$42ibn$-berlin.de...
    >
    > Thanks for all your replies so far.
    >
    > I can't post the entire block of code here for commercial reasons, but a
    > selection of the if statements are:
    >
    > if(difference == 0.000) {
    > strcpy(PFM_Date,"A5"); }
    >
    > if(difference == 0.052 || 0.053) {
    > strcpy(PFM_Date,"M25"); }
    >
    > if(difference == 0.894 || 0.895) {
    > strcpy(PFM_Date,"M29"); }
    >
    > if(difference == 0.947 || 0.948) {
    > strcpy(PFM_Date,"A17"); }
    >
    > where:
    >
    > difference is of type float
    > and PFM_Date[4] of type char.
    >
    > I am trying to set PFM_Date to a three-letter code if the conditions I've
    > posted have been met. Only one of these many if statements will ever be
    > true. My source file is of type .cpp in VC++ 6, SP5.


    Sounds like you need fixed point (exact) arithmetic, not floating point.
    The precision of floating point is not exact, you need to compare to some
    delta. In your case it seems like a delta of 0.0005 is adequate, but
    without the exact requirements, one cannot tell.

    Fixed point arithmetic is not directly supported by C, but you my want to
    look into counting promilles directly in a long.

    HTH,
    M4
    Martijn Lievaart, Jan 5, 2004
    #11
  12. root

    root Guest

    Re: C++ if statements - only last one is ever true (code)

    "Christof Krueger" <> wrote in message
    news:bt9kvf$h10$04$-online.com...
    > root wrote:
    >
    > > "Christof Krueger" <> wrote in message
    > > news:bt9j4m$dvq$07$-online.com...
    > >>>"root" <> wrote in message
    > >>>news:bt7mk1$42ibn$-berlin.de...
    > >>
    > >>That means that your if-condition is true when either (difference ==
    > >>0.947) is true, or if (0.948) is true. In C++ numeric values that are
    > >>not 0 _always_ return true.
    > >>In your posted code the last three strcpy-statements are executed, but
    > >>you only see the effect of the last one, because it overwrites the
    > >>contents of PFM_Date.
    > >>What you probably mean is
    > >>
    > >> if ( (difference == 0.947) || (difference == 0.948) ) {
    > >> strcpy(PFM_Date,"A17"); }

    > >
    > >
    > > Thanks for that. I've tried it and now PFM_Date is coming out as blank
    > > (it's being printed using a printf).

    > It's blank because none of the if-statements ever are true (I assume
    > because you test float numbers for equality).
    > Do you really want to test for the *exact* value 0.947 or the *exact*
    > value 0.948? Should the test fail for 0.9475? Or for 0.94700001? And
    > what's with 0.94699999?


    I'm basically comparing the result of a calculation (a division to be exact)
    against a table of alphanumeric codes. 0.9475 needs to be taken as 0.947
    with regards to what I need, as I only need the first three digits.

    Would it be a better idea, if I managed to do the division, get the decimal
    values, and convert them to integers, thus losing the remaining decimal
    values and not having to worry about if statements and float variables? As
    another poster pointed out, the OR part in the if statement is there to
    cover me for rounding errors (not really full-proof).

    For example, if after the division I end up with 158.947123456780.......,
    would it be a better idea (perhaps more robust?) to get 0.947 by taking the
    difference of the above number and the division using integer division (as I
    am currently doing), then multiplying 0.947 by, say 100, to get 947 and
    putting it in another, integer type variable?

    Thanks again to you all for your replies. Apologies for the slightly
    complicated post!
    root, Jan 5, 2004
    #12
  13. root

    root Guest

    Re: C++ if statements - only last one is ever true (code)

    "Paul" <> wrote in message
    news:363fefa012b65682d370e3d9a147ab38@news.1usenet.com...
    >
    > "root" <> wrote in message
    > news:bt9k3o$4o97p$-berlin.de...
    > > I know this is really bad programming, but I must check for those

    specific
    > > values. Maybe C++ isn't the best language for this.
    > >

    > Checking for exact floating point values is not only bad programming in

    C++,
    > it's bad programming in most other languages. Try the same thing with
    > Fortran, C, BASIC, Pascal -- you'll get the same problems.


    Perl perhaps?

    > What you need is to either use a library that gives you more precision
    > (usually these libraries are used for business calculations, where exact
    > arithmetic is mandatory), or use a language that has exact representation

    of
    > such numbers. Maybe COBOL.


    What, you mean the Complete and Obsolete Business Orientated Business
    Language? ;-)
    root, Jan 5, 2004
    #13
  14. Re: C++ if statements - only last one is ever true (code)

    root wrote:
    > "Christof Krueger" <> wrote in message
    > news:bt9kvf$h10$04$-online.com...
    >
    >>root wrote:
    >>
    >>
    >>>"Christof Krueger" <> wrote in message
    >>>news:bt9j4m$dvq$07$-online.com...
    >>>
    >>>>>"root" <> wrote in message
    >>>>>news:bt7mk1$42ibn$-berlin.de...
    >>>>
    >>>>That means that your if-condition is true when either (difference ==
    >>>>0.947) is true, or if (0.948) is true. In C++ numeric values that are
    >>>>not 0 _always_ return true.
    >>>>In your posted code the last three strcpy-statements are executed, but
    >>>>you only see the effect of the last one, because it overwrites the
    >>>>contents of PFM_Date.
    >>>>What you probably mean is
    >>>>
    >>>> if ( (difference == 0.947) || (difference == 0.948) ) {
    >>>> strcpy(PFM_Date,"A17"); }
    >>>
    >>>
    >>>Thanks for that. I've tried it and now PFM_Date is coming out as blank
    >>>(it's being printed using a printf).

    >>
    >>It's blank because none of the if-statements ever are true (I assume
    >>because you test float numbers for equality).
    >>Do you really want to test for the *exact* value 0.947 or the *exact*
    >>value 0.948? Should the test fail for 0.9475? Or for 0.94700001? And
    >>what's with 0.94699999?

    >
    >
    > I'm basically comparing the result of a calculation (a division to be exact)
    > against a table of alphanumeric codes. 0.9475 needs to be taken as 0.947
    > with regards to what I need, as I only need the first three digits.
    >
    > Would it be a better idea, if I managed to do the division, get the decimal
    > values, and convert them to integers, thus losing the remaining decimal
    > values and not having to worry about if statements and float variables? As
    > another poster pointed out, the OR part in the if statement is there to
    > cover me for rounding errors (not really full-proof).
    >
    > For example, if after the division I end up with 158.947123456780.......,
    > would it be a better idea (perhaps more robust?) to get 0.947 by taking the
    > difference of the above number and the division using integer division (as I
    > am currently doing), then multiplying 0.947 by, say 100, to get 947 and
    > putting it in another, integer type variable?

    I'm sure 100 was a typo and you mean 1000. But that is what I would have
    suggested. You could cast it to int (I think that always truncates
    towards zero, but correct me if I am wrong) and then check against your
    hard-coded values to do whatever you want to do.
    Because rounding errors can occur with FP arithmetics very easily, you
    probably still should check for ranges rather than for fixed numbers.

    What you would do at the moment is

    float a = <whatever>;
    float b = <whatever>;
    float c = a / b; // rounding errors!
    c -= (int)c // works well assuming you don't have negative numbers
    int d = (int)(c * 1000)
    with d containing numbers from 0 to 999

    If a and b are integral values, you could even do the following which is
    equivalent:

    int a = <whatever>;
    int b = <whatever>;
    int c = a % b; // modulo
    int d = (c * 1000) / b; // integer division rounds down (truncates)

    This code should be faster on common architectures (no, i can't prove
    it), and should be more predictible concerning rounding errors because
    no architecture dependent FP errors can occur. The only assumption made
    here is that integer division rounds towards zero.

    If you can rewrite your code like this depends on the nature of your
    calculation. With integer arithmetic you do not have rounding errors,
    but you should be very careful not to let your variables overflow. (e.g.
    the operation 70000*65000 already overflows an unsigned 32bit integer!)

    > Thanks again to you all for your replies. Apologies for the slightly
    > complicated post!
    >
    >



    --
    Regards,
    Christof Krueger
    Christof Krueger, Jan 6, 2004
    #14
  15. root

    root Guest

    Re: C++ if statements - only last one is ever true (code)

    "Christof Krueger" <> wrote in message
    news:btdsgo$re6$02$-online.com...
    > > "Christof Krueger" <> wrote in message
    > > news:bt9kvf$h10$04$-online.com...
    > >>
    > >>>"Christof Krueger" <> wrote in message
    > >>>news:bt9j4m$dvq$07$-online.com...
    > >>>>>"root" <> wrote in message
    > >>>>>news:bt7mk1$42ibn$-berlin.de...

    > > For example, if after the division I end up with

    158.947123456780.......,
    > > would it be a better idea (perhaps more robust?) to get 0.947 by taking

    the
    > > difference of the above number and the division using integer division

    (as I
    > > am currently doing), then multiplying 0.947 by, say 100, to get 947 and
    > > putting it in another, integer type variable?


    > I'm sure 100 was a typo and you mean 1000. But that is what I would have
    > suggested. You could cast it to int (I think that always truncates
    > towards zero, but correct me if I am wrong) and then check against your
    > hard-coded values to do whatever you want to do.
    > Because rounding errors can occur with FP arithmetics very easily, you
    > probably still should check for ranges rather than for fixed numbers.


    Hi again.
    Yes, it was a typo! tried it with 1,000 yesterday and it worked a treat. I
    did something similar to what you recommended below, though not in as few
    lines as you did.
    All's well that ends well.
    My thanks to the group, especially to you, Christof. You've been a great
    help.

    Hapy 2004 to you all!


    > What you would do at the moment is
    >
    > float a = <whatever>;
    > float b = <whatever>;
    > float c = a / b; // rounding errors!
    > c -= (int)c // works well assuming you don't have negative numbers
    > int d = (int)(c * 1000)
    > with d containing numbers from 0 to 999
    >
    > If a and b are integral values, you could even do the following which is
    > equivalent:
    >
    > int a = <whatever>;
    > int b = <whatever>;
    > int c = a % b; // modulo
    > int d = (c * 1000) / b; // integer division rounds down (truncates)
    >
    > This code should be faster on common architectures (no, i can't prove
    > it), and should be more predictible concerning rounding errors because
    > no architecture dependent FP errors can occur. The only assumption made
    > here is that integer division rounds towards zero.
    >
    > If you can rewrite your code like this depends on the nature of your
    > calculation. With integer arithmetic you do not have rounding errors,
    > but you should be very careful not to let your variables overflow. (e.g.
    > the operation 70000*65000 already overflows an unsigned 32bit integer!)
    root, Jan 6, 2004
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    18
    Views:
    450
    Magnus Lycka
    Feb 20, 2006
  2. sangram
    Replies:
    16
    Views:
    1,963
  3. Johny
    Replies:
    8
    Views:
    383
  4. bdb112
    Replies:
    45
    Views:
    1,318
    jazbees
    Apr 29, 2009
  5. Jason
    Replies:
    0
    Views:
    179
    Jason
    Jul 6, 2004
Loading...

Share This Page