Switch for floating !!

K

karthikbalaguru

Hi,

Why does the switch case statement does not have support
for floating points ?

int main(void)
{
int a = 10;
switch(a)
{
case 1:
printf("1 \n");
break;
case 2.5:
printf("2.5 \n");
break;
default:
printf("Other Number \n");
break;
}
return 0;
}

Is it so difficult for C library to support the floating point
in the above scenario ?
Anyone working on including the support for floating
points w.r.t switch statements for the future release ?

Thx in advans,
Karthik Balaguru
 
R

Richard Tobin

karthikbalaguru said:
Why does the switch case statement does not have support
for floating points ?

For one thing, equality comparisons for floating point are rarely
useful. Floating point can't exactly represent most numbers.
Is it so difficult for C library to support the floating point
in the above scenario ?

I think you misunderstand the term "C library". This has nothing
to do with the library, just the language.
Anyone working on including the support for floating
points w.r.t switch statements for the future release ?

Guess.

-- Richard
 
B

Bartc

karthikbalaguru said:
Hi,

Why does the switch case statement does not have support
for floating points ?

int main(void)
{
int a = 10;

You mean, float?
switch(a)
{
case 1:
printf("1 \n");
break;
case 2.5:
printf("2.5 \n");
break;
default:
printf("Other Number \n");
break;
}
return 0;
}

Is it so difficult for C library to support the floating point
in the above scenario ?

Switch is designed to work with integer values only. Working with floating
point would not have been impossible, but because it rules out the
possibility of a jump table, a switch would have little advantage over
if-else statements.

There are also problems in exactly matching one floating point number with
another; a special way of testing would be needed.
Anyone working on including the support for floating
points w.r.t switch statements for the future release ?

You will have a long wait.
 
S

Suvroc

Little modification:
You shoud do something like this:

#include <stdio.h>
#include <math.h>

// because 1.0 != 1.0 in floating point system
bool float_equal(float& a, float& b, float eps)
{
return (fabs(b-a)<eps);
}

int main(void)
{
float a = 10;

if (a == 1)
printf("1 \n");
else if (a == 2.5)
printf("2.5 \n");
else
printf("Other Number \n");
return 0;
}
 
K

karthikbalaguru

You mean, float?







Switch is designed to work with integer values only. Working with floating
point would not have been impossible, but because it rules out the
possibility of a jump table, a switch would have little advantage over
if-else statements.

There are also problems in exactly matching one floating point number with
another; a special way of testing would be needed.

Interesting !!
Do you mean to say that C does not have facility for exact Floating
Point
number validation or processing irrespective of the type of
processor ?

That is something unexpected from the C Language. I thought
it would do comparison operations correctly !!

I wonder, how C is used in algorithms !! :( :( Strange !!
Do they use some kind of fix while using with algorithms ?
Any ideas ?

Thx in advans,
Karthik Balaguru
 
R

Ralf Damaschke

karthikbalaguru said:
Interesting !!
Do you mean to say that C does not have facility for exact Floating
Point
number validation or processing irrespective of the type of
processor ?

See FAQ (http://c-faq.com/), esp. 14.1, 14.4a and 14.5.

You might also google for "What Every Computer Scientist Should Know About
Floating-Point Numbers [or was it really Arithmetics?]" by D. Goldberg.

-- Ralf
 
S

Suvroc

I forgot this.
It shoud be:
....
if (float_equal(a,1.0, 1e-6)
....
And in case of references, yes, it's my mistake.
 
B

Barry Schwarz

Interesting !!
Do you mean to say that C does not have facility for exact Floating
Point
number validation or processing irrespective of the type of
processor ?

C has the facility. The processor cannot produce the desired values.
for example
#include <stdio.h>
int main(void){
double x;
for (x = 0; x < 1.0; x += .1)
;
if (x == 1.0)
puts("Exact");
else
puts("Approximate");
return 0;
}
prints "Approximate" on most systems in use today. The reason is that
while 1.0 can be represented exactly on all systems, 0.1 cannot be on
most. I believe this is called limited precision.

(If I activate the decimal floating point feature of my system, it
prints "Exact" but that is why I said most, not all. Changing the
third clause of the for statement to
x += 1./11.
will result in "Approximate" on all systems I know of.)
That is something unexpected from the C Language. I thought
it would do comparison operations correctly !!

It does. You are under the mistaken impression that "arithmetic"
performed on a CPU follows the rules of arithmetic you learned in
school. On most systems
x = 999999999999999999999999.0;
x -= 1.0;
does not result in a change to the value of x. I believe this is
called limited significance.
I wonder, how C is used in algorithms !! :( :( Strange !!
Do they use some kind of fix while using with algorithms ?
Any ideas ?

Yes, many do. One method: Instead of comparing for exact equality,
they compare for very small differences. Something along the lines of
replacing my if statement above with
if (fabs(x-1.0) < 1e-8)

Search the archives. This has been discussed many times in great
detail.
 
C

CBFalconer

karthikbalaguru said:
Why does the switch case statement does not have support
for floating points ?

Because a floating point value is not an integer value.
 
C

CBFalconer

karthikbalaguru said:
.... snip ...

Do you mean to say that C does not have facility for exact
Floating Point number validation or processing irrespective of
the type of processor ?

When you can give me an exact representation of the number 1/3 in a
floating point system, which is not based on a modulus containing
3, I will give you some further exact floating point expressions.
 
J

James Kuyper

CBFalconer said:
Because a floating point value is not an integer value.

A floating point value can be an integer value, such as 3.0.

However, whether or not that is the case, how does that constitute an
answer to the question? The question was not about what the standard
requires. The question was, does the standard require it?
 
C

CBFalconer

James said:
A floating point value can be an integer value, such as 3.0.

However, whether or not that is the case, how does that constitute
an answer to the question? The question was not about what the
standard requires. The question was, does the standard require it?

No, that is a non-integral value which has a zero fractional part.
Really. And yes, the standard demands integers. They may be used
to index a jump table, for example.
 
M

mijoryx

Yes, many do.  One method: Instead of comparing for exact equality,
they compare for very small differences.  Something along the lines of
replacing my if statement above with
    if (fabs(x-1.0) < 1e-8)

Search the archives.  This has been discussed many times in great
detail.

Just for completeness, the library macro is
#include <math.h> /* int isunordered( x, y ) */
#include <stdio.h>

int main() {
float a = 1.0;
float b = 0;
int i;
for (i=0; i<10; i++) b += .1;
if (isunordered(a,b)) printf("a and b are considered equal\n");
}

without C99 you can fake it with:
#define isunordered(x,y) (fabs(x-y)>FLT_EPSILON)
 
M

mijoryx

Just for completeness, the library macro is
#include <math.h> /* int isunordered( x, y ) */
#include <stdio.h>

int main() {
float a = 1.0;
float b = 0;
int i;
for (i=0; i<10; i++) b += .1;
if (isunordered(a,b)) printf("a and b are considered equal\n");

}

without C99 you can fake it with:
#define isunordered(x,y) (fabs(x-y)>FLT_EPSILON)
sorry, fabs is C99, too.
i meant:
#define isunordered(x,y) (abs(x-y)>FLT_EPSILON)
add more parens to use it for expressions
 
M

Martin Ambuhl

if (isunordered(a,b)) printf("a and b are considered equal\n");
without C99 you can fake it with:
#define isunordered(x,y) (fabs(x-y)>FLT_EPSILON)

No, you can't. If at least one of the arguments is NaN, the arguments
are considered unordered. The C99 macro isunordered() does not test for
near equality, in spite of your claim otherwise. In fact, if neither is
NaN then isunordered will tell you that there is an ordered relation
between them, even if they have exactly the same value.
 
M

Martin Ambuhl

sorry, fabs is C99, too.
i meant:
#define isunordered(x,y) (abs(x-y)>FLT_EPSILON)
add more parens to use it for expressions

All you have done is make your error worse. Before you only were
claiming that isunordered did something completely different from what
it really does. You have made if worse by suggesting:
1) that fabs is C99 and not C89. fabs has always been part of standard
C.
2) that supplying a floating-point value as the argument to abs() will
be useful. Since abs() takes an integer argument, the test with
FLT_EPSILON is rather silly.
 
J

James Kuyper

CBFalconer said:
No, that is a non-integral value which has a zero fractional part.

No, that is an integral value expressed in a floating point type. The
literals 3, 3U, 3LL, 3.0, 3.0F, '\03', L'\03' all have different types,
but they all represent the same value, which is an integral value.
Really. And yes, the standard demands integers. They may be used
to index a jump table, for example.

If you don't know the answer to the question, that's fine; but please
don't state that "the standard demands integers" as if it were an answer
to the question "why does the standard demand integers?".

If the standard did not demand integers, there would still be nothing to
prevent the implementation from using jump tables when integers were in
fact used.
 
J

James Kuyper

James said:
No, that is an integral value expressed in a floating point type. The
literals 3, 3U, 3LL, 3.0, 3.0F, '\03', L'\03' all have different types,
but they all represent the same value, which is an integral value.

Note, in particular, section 6.3.1.4p2: "When a value of integer type is
converted to a real floating type, if the value being converted can be
represented exactly in the new type, it is unchanged."

In other words, (double)3 has the same value as 3, just a different
type. If you insist that 3 has a different value than 3.0, then "the
value being converted" by the expression (double)3 can not "be
represented exactly in the new type", in which case 6.3.1.4p2 does not
apply; it could never apply - it would in fact be completely meaningless.
 
J

James Kuyper

karthikbalaguru said:
Interesting !!
Do you mean to say that C does not have facility for exact Floating
Point
number validation or processing irrespective of the type of
processor ?

The problem is not specific to C; it's inherent in all floating point
arithmetic. The fundamental problem is that a floating point type
containing a fixed, finite number of bits can represent only a finite
number of different numeric values. MOST floating point operations will
produce a value that cannot be represented exactly, the best that they
can do is produce the closest representable value, and in many cases
it's not even feasible to guarantee that (consider, for instance,
sin(DBL_MAX)).

Since most floating point operations introduce a certain amount of
error, it's generally not a wise idea to compare floating point values
for exact equality.
That is something unexpected from the C Language. I thought
it would do comparison operations correctly !!

5.2.4.2.2p5: "The accuracy of the floating-point operations (+, -, *, /)
and of the library functions in <math.h> and <complex.h> that return
floating-point results is implementation defined, as is the accuracy of
the conversion between floating-point internal representations and
string representations performed by the library functions in <stdio.h>,
<stdlib.h>, and <wchar.h>. The implementation may state that the
accuracy is unknown."

Note that this allows both for an arbitrarily inaccurate floating point
implementation (such that -DBL_MAX == DBL_MAX), so long as the
implementation documents that "== performs comparisons on doubles with
an accuracy of +/-2*DBL_MAX". However, the same exact wording also
allows an implementation that achieves exactly the maximum possible
degree of accuracy allowed within the limitations I've mentioned above.

Note that if a C99 implementation pre-defines the __STDC_IEC_559__
macro, than the requirements of IEEE/IEC 60559 apply, which gives you a
lot of guarantees that the C standard itself does not provide.

While the C standard does not specify the accuracy of floating point
operations, in C99 it added a macro in <float.h> named FLT_EVAL_METHOD
which give you some information about what accuracy an implementation
actually provides, and a #pragma named STDC FP_CONTRACT in <math.h> that
gives you some control over the the accuracy.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top