By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,285 Members | 2,124 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,285 IT Pros & Developers. It's quick & easy.

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

P: n/a
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!
Jul 22 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
In article <bt************@ID-193745.news.uni-berlin.de>,
"root" <ae***@despammed.com> 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-lit...html#faq-29.17

Jul 22 '05 #2

P: n/a
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

Jul 22 '05 #3

P: n/a
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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)
Jul 22 '05 #4

P: n/a
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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.
Jul 22 '05 #5

P: n/a
root wrote:
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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

Jul 22 '05 #6

P: n/a
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" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-berlin.de...
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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.

Jul 22 '05 #7

P: n/a
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
root wrote:
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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.
Jul 22 '05 #8

P: n/a
root wrote:
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
root wrote:

"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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

Jul 22 '05 #9

P: n/a

"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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


Jul 22 '05 #10

P: n/a
On Sun, 04 Jan 2004 17:27:39 +0000, root wrote:
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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

Jul 22 '05 #11

P: n/a
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
root wrote:
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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!
Jul 22 '05 #12

P: n/a
"Paul" <pa**@paul.com> wrote in message
news:36******************************@news.1usenet .com...

"root" <ae***@despammed.com> wrote in message
news:bt************@ID-193745.news.uni-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? ;-)
Jul 22 '05 #13

P: n/a
root wrote:
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
root wrote:

"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...

>"root" <ae***@despammed.com> wrote in message
>news:bt************@ID-193745.news.uni-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

Jul 22 '05 #14

P: n/a
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...

"Christof Krueger" <ne**@pop2wap.net> wrote in message
news:bt*************@news.t-online.com...
>>"root" <ae***@despammed.com> wrote in message
>>news:bt************@ID-193745.news.uni-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!)

Jul 22 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.