Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Switch for floating !!

23 views
Skip to first unread message

karthikbalaguru

unread,
Feb 14, 2009, 5:54:27 AM2/14/09
to
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

Richard Tobin

unread,
Feb 14, 2009, 6:12:04 AM2/14/09
to
In article <1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com>,
karthikbalaguru <karthikb...@gmail.com> wrote:

>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
--
Please remember to mention me / in tapes you leave behind.

Bartc

unread,
Feb 14, 2009, 6:34:07 AM2/14/09
to

"karthikbalaguru" <karthikb...@gmail.com> wrote in message
news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...

> 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.

--
bartc

Lorenzo Villari

unread,
Feb 14, 2009, 8:45:01 AM2/14/09
to

"karthikbalaguru" <karthikb...@gmail.com> ha scritto nel messaggio
news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...

> 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 ?

No but you can do this:

#include <stdio.h>


int main(void)
{
int a = 10;

if (a == 1)
printf("1 \n");
else if (a == 2.5)
printf("2.5 \n");
else


printf("Other Number \n");

return 0;
}

Suvroc

unread,
Feb 14, 2009, 10:50:13 AM2/14/09
to
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;
}

Użytkownik "Lorenzo Villari" <vll...@alice.it> napisał w wiadomości
news:4996cadc$0$1125$4faf...@reader1.news.tin.it...

karthikbalaguru

unread,
Feb 14, 2009, 11:08:56 AM2/14/09
to
On Feb 14, 4:34 pm, "Bartc" <ba...@freeuk.com> wrote:
> "karthikbalaguru" <karthikbalagur...@gmail.com> wrote in message

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 ?

Ralf Damaschke

unread,
Feb 14, 2009, 11:35:59 AM2/14/09
to
karthikbalaguru wrote:

> On Feb 14, 4:34 pm, "Bartc" <ba...@freeuk.com> wrote:

>> 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 ?

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

Lorenzo Villari

unread,
Feb 14, 2009, 11:48:01 AM2/14/09
to

"Suvroc" <suv...@o2.pl> ha scritto nel messaggio
news:gn6si1$lbf$1...@julia.coi.pw.edu.pl...

> #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);
> }

Why define a function and then not using it? And C doesn't have references
yet...


Suvroc

unread,
Feb 14, 2009, 11:53:26 AM2/14/09
to
I forgot this.
It shoud be:
...
if (float_equal(a,1.0, 1e-6)
...
And in case of references, yes, it's my mistake.

Użytkownik "Lorenzo Villari" <vll...@alice.it> napisał w wiadomości

news:4996f5c1$0$1108$4faf...@reader4.news.tin.it...

Barry Schwarz

unread,
Feb 14, 2009, 2:44:45 PM2/14/09
to

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.

--
Remove del for email

blargg

unread,
Feb 14, 2009, 5:55:06 PM2/14/09
to
Bartc wrote:
> karthikbalaguru wrote:
[...]

> > 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.

Even when a compiler doesn't generate a jump table, it can still generate
a binary search. But then the user could do so, and get the exact same
code, unlike with a jump table.

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

Which is the real killer; switch using a floating-point value is mostly
useful only in buggy code.

Golden California Girls

unread,
Feb 14, 2009, 7:30:19 PM2/14/09
to
karthikbalaguru wrote:
> 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 ?

Library has nothing to do with it.

> Anyone working on including the support for floating
> points w.r.t switch statements for the future release ?

Of course not silly. The granularity of a float is less than the granularity of
an unsigned long long. No need.

Before you post about this again, take a class in numerical analysis.

CBFalconer

unread,
Feb 14, 2009, 9:32:53 PM2/14/09
to
karthikbalaguru wrote:
>
> Why does the switch case statement does not have support
> for floating points ?

Because a floating point value is not an integer value.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

CBFalconer

unread,
Feb 14, 2009, 9:37:15 PM2/14/09
to
karthikbalaguru wrote:
>
... 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.

James Kuyper

unread,
Feb 14, 2009, 10:23:50 PM2/14/09
to
CBFalconer wrote:
> karthikbalaguru wrote:
>> Why does the switch case statement does not have support
>> for floating points ?
>
> 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?

CBFalconer

unread,
Feb 14, 2009, 11:29:11 PM2/14/09
to

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.

mij...@yahoo.com

unread,
Feb 15, 2009, 4:04:39 AM2/15/09
to
On Feb 14, 1:44 pm, Barry Schwarz <schwa...@dqel.com> wrote:

> >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.

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)

mij...@yahoo.com

unread,
Feb 15, 2009, 4:18:19 AM2/15/09
to
sorry, fabs is C99, too.
i meant:
#define isunordered(x,y) (abs(x-y)>FLT_EPSILON)
add more parens to use it for expressions

Martin Ambuhl

unread,
Feb 15, 2009, 4:45:35 AM2/15/09
to
mij...@yahoo.com wrote:

> 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.

Martin Ambuhl

unread,
Feb 15, 2009, 4:51:49 AM2/15/09
to
mij...@yahoo.com wrote:

>> 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

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.

James Kuyper

unread,
Feb 15, 2009, 6:00:44 AM2/15/09
to
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>> karthikbalaguru wrote:
>>>
>>>> Why does the switch case statement does not have support
>>>> for floating points ?
>>> 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?
>
> 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.

James Kuyper

unread,
Feb 15, 2009, 6:12:54 AM2/15/09
to
James Kuyper wrote:
> CBFalconer wrote:
>> James Kuyper wrote:
>>> CBFalconer wrote:
>>>> karthikbalaguru wrote:
>>>>
>>>>> Why does the switch case statement does not have support
>>>>> for floating points ?
>>>> 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?
>>
>> 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.

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.

James Kuyper

unread,
Feb 15, 2009, 6:31:18 AM2/15/09
to
karthikbalaguru wrote:
> On Feb 14, 4:34 pm, "Bartc" <ba...@freeuk.com> wrote:
...

>> 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 ?

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.

nick_keigh...@hotmail.com

unread,
Feb 15, 2009, 9:44:02 AM2/15/09
to
On 15 Feb, 09:18, mijo...@yahoo.com wrote:
> On Feb 15, 3:04 am, mijo...@yahoo.com wrote:
> > On Feb 14, 1:44 pm, Barry Schwarz <schwa...@dqel.com> wrote:

<snip>

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

no. fabs() was present in C89 (the 1989 C standard)
and maybe even earlier.

> i meant:
> #define isunordered(x,y) (abs(x-y)>FLT_EPSILON)
> add more parens to use it for expressions

that looks dubious


Han from China

unread,
Feb 15, 2009, 4:35:19 AM2/15/09
to
CBFalconer wrote:
> karthikbalaguru wrote:
>>
>> Why does the switch case statement does not have support
>> for floating points ?
>
> Because a floating point value is not an integer value.

Brilliant answer, Chucky.

Kid: "Why is the sky blue instead of neon pink?"
CBFalconer: "Because neon pink isn't blue."


Yours,
Han from China

--
"Only entropy comes easy." -- Anton Chekhov

nick_keigh...@hotmail.com

unread,
Feb 15, 2009, 10:21:17 AM2/15/09
to
On 15 Feb, 14:44, nick_keighley_nos...@hotmail.com wrote:
> On 15 Feb, 09:18, mijo...@yahoo.com wrote:
> > On Feb 15, 3:04 am, mijo...@yahoo.com wrote:
> > > On Feb 14, 1:44 pm, Barry Schwarz <schwa...@dqel.com> wrote:

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

in an earlier post you implied unordered was equivalent
to equal. So if they aren't ordered they can be considered
to be equivalent.

Which looks ok for fabs. Lets say 'e' is just smaller
than epsilon

2.0 == 2.0
2.0 == 2.0 + e
2.0 != 1.0
2.0 != 2.9

> > sorry, fabs is C99, too.
>
> no. fabs() was present in C89 (the 1989 C standard)
> and maybe even earlier.
>
> > i meant:
> > #define isunordered(x,y) (abs(x-y)>FLT_EPSILON)
> > add more parens to use it for expressions
>
> that looks dubious

so now try your abs version

2.0 == 2.9

which looks wrong to me...


Richard Tobin

unread,
Feb 15, 2009, 1:29:09 PM2/15/09
to
In article <49979A17...@yahoo.com>,
CBFalconer <cbfal...@maineline.net> wrote:

>>> 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?

>No, that is a non-integral value which has a zero fractional part.
>Really.

There may be interesting discussions to be had about whether a
mathematical integer is the same as the corresponding real number,
but none of them apply to C's ints and doubles.

Barry Schwarz

unread,
Feb 15, 2009, 2:30:53 PM2/15/09
to

In addition to all the other problems that have been pointed out, when
you finally do calculate the absolute difference between the values,
you need to compare it against a "scaled adjusted" value of
FLT_EPSILON. FLT_EPSILON is the smallest value that can be added to
1.0F to produce a different value. A typical value is 1E-5. If the
two values in question were 1E-20 and 1E-21, comparing against 1E-5
makes no sense.

mij...@yahoo.com

unread,
Feb 15, 2009, 2:44:12 PM2/15/09
to

appologies.
clearly i should not attempt to post things right before
going to bed (better to read it again with brighter eyes).
i confess i know next to nothing about isunordered
(yes, yes, don't make claims unless you're sure. point taken). my
actual code uses
fabsf(a.f - b.f) > FLT_EPSILON
but splint complained about unknown function fabsf
so while trying to make it happy, the code briefly
became
fabs(a.f - b.f) > FLT_EPSILON
which became garbled in my memory as fabs and abs.
so erroneous boasting and sleepy fingers aside,
what's the best test for "close-enough" floats?
the program above in the thread makes no attempt to
do this, relying on an external mental model of
the arithmetic to proclaim "approximately".

luser-ex-trolley

Martin Ambuhl

unread,
Feb 15, 2009, 3:33:25 PM2/15/09
to
nick_keigh...@hotmail.com wrote:

> in an earlier post you implied unordered was equivalent
> to equal.

Which is, of course, completely wrong.

Keith Thompson

unread,
Feb 15, 2009, 3:47:13 PM2/15/09
to
mij...@yahoo.com writes:
[...]

> so erroneous boasting and sleepy fingers aside,
> what's the best test for "close-enough" floats?
[...]

I don't think there is a "best test" for "close-enough" floats.

For integers, of course, equality is easy; two integers are either
equal or unequal, and even two very close numbers like 2147483646 and
2147483647 are clearly unequal. But even for integers, you might want
to know whether two values are "close enough" for some purpose.
Obviously the meaning of "close enough" depends on just what your
purpose is.

Since stored floating-point values, unlike integer values, are usually
approximations of some mathematical real value, comparing two stored
values for equality is often not useful, so we have to fall back to
some kind of "close enough" comparison. But determining what's "close
enough" depends on the application, and in particular on how the two
values being compared were computed.

--
Keith Thompson (The_Other_Keith) k...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

mij...@yahoo.com

unread,
Feb 15, 2009, 5:56:04 PM2/15/09
to
On Feb 15, 2:47 pm, Keith Thompson <ks...@mib.org> wrote:
> Obviously the meaning of "close enough" depends on just what your
> purpose is.
>
> Since stored floating-point values, unlike integer values, are usually
> approximations of some mathematical real value, comparing two stored
> values for equality is often not useful, so we have to fall back to
> some kind of "close enough" comparison.  But determining what's "close
> enough" depends on the application, and in particular on how the two
> values being compared were computed.
>

understood. how about some specifics.
I'd like to be able to compare floats in a
coordinate pair to determine if they will result
in the same XPoint (pair of short integers)
after passing through the same transformation
matrix and converted to shorts.
fabsf(a.f-b.f)>FLT_EPSILON
appears to be working (I don't expect to be using
values that push the boundaries of the float
representation). I need floats (or maybe fixed-point)
to use fractional scaling and sin and cos for rotations.
am i going to run into trouble comparing cos(0.0)
with 1.0?

> --
> Keith Thompson (The_Other_Keith) k...@mib.org  <http://www.ghoti.net/~kst>
> Nokia
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"

that's such a great show.
luXer-ex-troXX

Bartc

unread,
Feb 15, 2009, 7:14:40 PM2/15/09
to
mij...@yahoo.com wrote:
> On Feb 15, 2:47 pm, Keith Thompson <ks...@mib.org> wrote:

>> some kind of "close enough" comparison. But determining what's "close
>> enough" depends on the application, and in particular on how the two
>> values being compared were computed.
>>
>
> understood. how about some specifics.
> I'd like to be able to compare floats in a
> coordinate pair to determine if they will result
> in the same XPoint (pair of short integers)
> after passing through the same transformation
> matrix and converted to shorts.
> fabsf(a.f-b.f)>FLT_EPSILON
> appears to be working (I don't expect to be using
> values that push the boundaries of the float
> representation). I need floats (or maybe fixed-point)
> to use fractional scaling and sin and cos for rotations.
> am i going to run into trouble comparing cos(0.0)
> with 1.0?

cos(0) is likely to be exactly 1.0, but in general there will be problems.

Suppose you have a 2x2 rotation matrix and want to find out if it specifies
a rotation of exactly 90 degrees, it's unlikely to be an exact match with
((0 1) (-1 0)), depending on how it was calculated. (For example, try
combining two matrices each rotating 45 degrees.)

(In this example, you might apply rounding to the matrix, so that
((0.000009929, 0.99999352),(-1.000000271,-0.00000994)) 'snaps' to ((0.0,
1.0),(-1.0,0.0)), which will match with ((0,1),(-1,0)). You can then assume
a 90 degree rotation, but use the adjusted matrix to do the calculations.)


--
bartc

mij...@yahoo.com

unread,
Feb 15, 2009, 7:35:34 PM2/15/09
to
On Feb 15, 6:14 pm, "Bartc" <ba...@freeuk.com> wrote:

It's looking like 1e-5 will suit my purposes better than
FLT_EPSILON. But I just discovered that this is all
wholy unnecessary since XFillPolygon will add a
closing segment by itself (I had been comparing the
ending and beginning points (in userspace, hence floats)
to decide whether to add a copy of the beginning
point to the path before handing it off to XFillPolygon.
I do still need to compare floats in other contexts,
but these are likely to be identical copies so direct
comparison will work (or maybe fabsf>1e-5).

Thanks to all for the advice and tollerance.

luXer-ex-troXX

Gordon Burditt

unread,
Feb 15, 2009, 9:06:33 PM2/15/09
to
>understood. how about some specifics.
>I'd like to be able to compare floats in a
>coordinate pair to determine if they will result
>in the same XPoint (pair of short integers)
>after passing through the same transformation
>matrix and converted to shorts.
>fabsf(a.f-b.f)>FLT_EPSILON
>appears to be working (I don't expect to be using
>values that push the boundaries of the float
>representation). I need floats (or maybe fixed-point)
>to use fractional scaling and sin and cos for rotations.
>am i going to run into trouble comparing cos(0.0)
>with 1.0?

You're likely to have trouble comparing (float) 0.1 with (double)
0.1 .

You're likely to have trouble with (0.1 + 0.1 + 0.1 + 0.1 + 0.1 +
0.1 + 0.1 + 0.1 + 0.1 + 0.1) == 1.0 . People writing for loops
like: for (d = 0; d < 1.0; d += 0.1) { ... } run into this problem
often, with the loop getting run one too many or one too few times.

You are likely to have trouble with cos(something that *ought to be*
zero) not exactly equalling 1.0 .

In short, exact comparisons involving floating point are usually a bug.

You need a reasonable method of determining whether two points are,
in fact, the same point, and this is often a matter of application-specific
considerations, *NOT* the accuracy of floating point itself. It
is rare that your real-world data is so accurate that floating-point
roundoffs swamp measurement error, especially using doubles. How
many things can you measure to 10 (14 for IEEE doubles) significant
digits? currency, maybe.

For example, if you are plotting the location of telephone poles,
if the centers of two poles are less than two inches apart, they
are the same pole, because real poles have a radius of more than 2
inches. And if your GPS, which you use to measure the location of
poles, is only accurate to 10 feet, you probably need to consider
poles closer than 10 feet to be the same pole (although I suspect
some real poles are closer than that, yet are different poles).

CBFalconer

unread,
Feb 15, 2009, 10:16:40 PM2/15/09
to
James Kuyper wrote:
> CBFalconer wrote:
>
... snip ...

>
>> 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.

If you bother to read the portion you quoted, above, you may notice
an example indicating why integers are needed.

CBFalconer

unread,
Feb 15, 2009, 10:31:45 PM2/15/09
to
James Kuyper wrote:
> CBFalconer wrote:
>> James Kuyper wrote:
>>
... snip ...

>>
>>> 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.
>
> 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?".

Don't make such intimations. If you examine the quote above, you
will see what the question actually was.

And a possible implementation of 32 bit floating point could
express 3.0 as (hex):

7e 80 00 00

in place of:

00 00 00 03 (hi byte first, integer)

and these patterns will have a hard time indexing the same location
in a jump table. If you have no idea how floating point values are
built, say so.

karthikbalaguru

unread,
Feb 16, 2009, 3:30:27 AM2/16/09
to
On Feb 14, 9:35 pm, Ralf Damaschke <rws...@gmx.de> wrote:
> karthikbalaguru wrote:
> > On Feb 14, 4:34 pm, "Bartc" <ba...@freeuk.com> wrote:
> >> 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 ?
>
> 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.
>

Interesting info !! :):)

Karthik Balaguru

karthikbalaguru

unread,
Feb 16, 2009, 4:01:25 AM2/16/09
to
On Feb 15, 12:44 am, Barry Schwarz <schwa...@dqel.com> wrote:
> On Sat, 14 Feb 2009 08:08:56 -0800 (PST), karthikbalaguru

>
>
>
> <karthikbalagur...@gmail.com> wrote:
> >On Feb 14, 4:34 pm, "Bartc" <ba...@freeuk.com> wrote:
> >> "karthikbalaguru" <karthikbalagur...@gmail.com> wrote in message
>
> >>news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...
>
> >> > 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.
>
> >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)

Cool idea !!

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

hmm. I will try to look into those archives also.

Karthik

nick_keigh...@hotmail.com

unread,
Feb 16, 2009, 4:41:53 AM2/16/09
to
please don't top-post. Post your reply after the text you
are replying to. I have re-arranged your post.

On 14 Feb, 15:50, "Suvroc" <suv...@o2.pl> wrote:>
> U¿ytkownik "Lorenzo Villari" <vll...@alice.it> napisa³ w
> wiadomo¶cinews:4996cadc$0$1125$4faf...@reader1.news.tin.it...
> > "karthikbalaguru" <karthikbalagur...@gmail.com> ha scritto nel messaggio
> >news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...

> >> 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 ?
>
> > No but you can do this:
>
> > #include <stdio.h>


>
> > int main(void)
> > {
> > int a = 10;
>

> > if (a == 1)

this can never be true

> > printf("1 \n");
> > else if (a == 2.5)

this can never be true

> > printf("2.5 \n");
> > else


> > printf("Other Number \n");
>

> > return 0;
> >
>
> Little modification:
> You shoud do something like this:
>
> #include <stdio.h>
> #include <math.h>
>
> // because 1.0 != 1.0 in floating point system

since when?

> bool float_equal(float& a, float& b, float eps)

this is not C. It's pretty crap c++ as well

> {
>     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;}

you never call float_equal()


James Kuyper

unread,
Feb 16, 2009, 6:15:01 AM2/16/09
to
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>
> ... snip ...
>>> 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.
>
> If you bother to read the portion you quoted, above, you may notice
> an example indicating why integers are needed.

Since I referred to the portion you underlined in my response, in the
course of refuting the idea that allowing jump tables makes integers a
necessity, I think you should have been able to concluded that I did in
fact read that portion.


The fact that you did not reach that conclusion suggests to me that you
didn't bother reading the last paragraph of my response. Let me expand
on the counterargument that you apparently didn't notice. Let's assume
the following:

1) The standard is modified as follows (Note: I am NOT proposing that it
be changed in this fashion, I'm explaining why the reasons you've given
are insufficient argument against changing it in this fashion).
a) 6.8.4.2p1: allow the controlling expression in a switch() statement
to have any scalar type.
b) 6.8.4.2p3: allow the expression in a case label to be any constant
expression with scalar type.

2) A program contains a switch statement for which a jump table would be
a good way to implement it, under the current rules.

What feature of the changes to the standard described in item 1) would
prevent an implementation from using a jump table to implement the
switch statement described in item 2?

James Kuyper

unread,
Feb 16, 2009, 6:59:40 AM2/16/09
to
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>> James Kuyper wrote:
>>>
> ... snip ...
>>>> 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?
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

My apologies for the confusion: that last sentence was supposed to have
the word "why" just before the word "does".

>>> 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?".

...

> And a possible implementation of 32 bit floating point could
> express 3.0 as (hex):
>
> 7e 80 00 00
>
> in place of:
>
> 00 00 00 03 (hi byte first, integer)
>
> and these patterns will have a hard time indexing the same location
> in a jump table.

The expressions used in case labels are required to be converted to the
promoted type of the controlling expression before comparison (the
conversion would normally occur at compile time). Therefore, the fact
that those case label expressions might have a different representation
than the controlling expression before conversion is irrelevant.

I'll readily concede that having a controlling expression that is a
floating point type would make it less likely for jump tables to be
feasible, though it would still be possible in certain special cases. So
what? The same is true if the controlling expression has the type
intmax_t and the case label expressions have no simple pattern. The
standard does not require implementation by jump tables, it only allows
implementation by jump tables.

If the standard were changed to allow non-integral controlling
expressions in switch() statements, that change would not in any way
prevent the use of jump tables for any switch() statement that is
allowed under the current rules, if a jump table happens to be a good
way to implement that statement.

The key issue with allowing floating point controlling expressions is
not whether it would be feasible to support them, but whether it would
be a good idea to encourage people to use them. Writing a switch()
statement with a floating point controlling expression would be a bad
idea, even if it were allowed, for precisely the same reason it would be
a bad idea to write the corresponding series of if-else statements.
That's because the conditions of the corresponding if()'s would compare
floating point values for equality, a reasonable thing to do only in
certain special cases.

CBFalconer

unread,
Feb 16, 2009, 5:23:53 PM2/16/09
to
James Kuyper wrote:
>
... snip ...
>
> My apologies for the confusion: that last sentence was supposed
> to have the word "why" just before the word "does".
>
... snip ...

>
> The key issue with allowing floating point controlling expressions
> is not whether it would be feasible to support them, but whether
> it would be a good idea to encourage people to use them. Writing a
> switch() statement with a floating point controlling expression
> would be a bad idea, even if it were allowed, for precisely the
> same reason it would be a bad idea to write the corresponding
> series of if-else statements. That's because the conditions of the
> corresponding if()'s would compare floating point values for
> equality, a reasonable thing to do only in certain special cases.

Among other things the present restrictions make it easy for the
compiler to examine the set of switch values (they are all listed
in the statement) and decide between generating if/else expressions
or a jump table. That decision can result in major savings in code
space and/or execution time.

I'm glad you have identified the fundamental cause of our
'argument', which really doesn't exist. It shows how much
difference one small missing word can cause.

Keith Thompson

unread,
Feb 16, 2009, 5:52:20 PM2/16/09
to
CBFalconer <cbfal...@yahoo.com> writes:
> James Kuyper wrote:
>>
> ... snip ...
>>
>> My apologies for the confusion: that last sentence was supposed
>> to have the word "why" just before the word "does".
>>
> ... snip ...
>>
>> The key issue with allowing floating point controlling expressions
>> is not whether it would be feasible to support them, but whether
>> it would be a good idea to encourage people to use them. Writing a
>> switch() statement with a floating point controlling expression
>> would be a bad idea, even if it were allowed, for precisely the
>> same reason it would be a bad idea to write the corresponding
>> series of if-else statements. That's because the conditions of the
>> corresponding if()'s would compare floating point values for
>> equality, a reasonable thing to do only in certain special cases.
>
> Among other things the present restrictions make it easy for the
> compiler to examine the set of switch values (they are all listed
> in the statement) and decide between generating if/else expressions
> or a jump table. That decision can result in major savings in code
> space and/or execution time.
[...]

Allowing floating-point controlling expressions would not make the
compiler's job any more difficult. It could still generate a jump
table in all the cases where it can do so now, and detecting those
cases is at worst trivially more difficult (if it's floating-point,
don't use a jump table).

There are good reasons for disallowing floating-point controlling
expressions, but difficulty for the compiler isn't one of them.

Antoninus Twink

unread,
Feb 16, 2009, 6:00:36 PM2/16/09
to
On 16 Feb 2009 at 22:23, CBFalconer wrote:
> James Kuyper wrote:
>> The key issue with allowing floating point controlling expressions
>> is not whether it would be feasible to support them, but whether
>> it would be a good idea to encourage people to use them.
[snip]

> Among other things the present restrictions make it easy for the
> compiler to examine the set of switch values (they are all listed
> in the statement) and decide between generating if/else expressions
> or a jump table.

My god, you really have completely lost the power of logical thought,
haven't you? (I'm charitably assuming that you once possessed it, before
old age turned your brain into mush.)

I truly wonder that James Kupyer or anyone else can possibly have the
patience to try to conduct a technical discussion with you. The rest of
us are jumping up and down with frustration just watching your repeated
failures to grasp the simplest point that's made to you.

CBFalconer

unread,
Feb 16, 2009, 7:02:44 PM2/16/09
to
James Kuyper wrote:
> CBFalconer wrote:
>> James Kuyper wrote:
>>> CBFalconer wrote:
>>>
>> ... snip ...
>>>> 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.
>>
>> If you bother to read the portion you quoted, above, you may notice
>> an example indicating why integers are needed.
>
> Since I referred to the portion you underlined in my response, in the
> course of refuting the idea that allowing jump tables makes integers a
> necessity, I think you should have been able to concluded that I did in
> fact read that portion.
>
> The fact that you did not reach that conclusion suggests to me that you
> didn't bother reading the last paragraph of my response. Let me expand
> on the counterargument that you apparently didn't notice. Let's assume
> the following:

The following is a copy of my original reply to you. It includes
every word of your reply (as evidenced by the absence of <snip>
markers). In that light, I cannot follow your 'did not read'
comment. I answered the question you posed. I included an example
showing why the standard was so written.

! James Kuyper wrote:
!> CBFalconer wrote:
!>> karthikbalaguru wrote:
!>>
!>>> Why does the switch case statement does not have support
!>>> for floating points ?
!>>
!>> 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?
!
! 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.

... snip ...

> What feature of the changes to the standard described in item 1)
> would prevent an implementation from using a jump table to
> implement the switch statement described in item 2?

In a separate answer somewhere in this thread I gave an example of
floating and integer representation of the number 3. Remember that
the idea is to have rapid execution. Any such intermixing of
representation would require fairly extensive code to test and
convert the representation, before indexing a pointer to a jump
table with it. Or it would require two separate sets of code
generated. Any such is contrary to the spirit of C, and totally
unnecessary. At worst, avoidance requires anointing the switch
statement with a cast.

Kaz Kylheku

unread,
Feb 16, 2009, 8:24:46 PM2/16/09
to
On 2009-02-14, karthikbalaguru <karthikb...@gmail.com> wrote:
> Hi,

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

The likely reason is that switch statements are not often used for values that
represent mathematical integers, but rather values that represent codes:
characters representing elements of text, whose codes are arbitrarily assigned,
and enumerations representing types, states, graph labels, error codes, and
the like.

Rarely is a switch used for some kind of mathematical property, because
mathematical properties tend to generate infinite sets.

Would you use a giant switch statement to distinguish fibonacci integers from
other integers?

> 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;
> }

You need a better example to actually rationalize switching on floating point
values. I.e. show some numerical code that benefits from a floating point
switch statement.

Her is an idea:

#include <math.h>

// copysign is a C99 function

switch (copysign(1.0, x)) {
case -1.0:
// x is negative
break;
case 0:
// x is zero
break;
case 1.0:
// x is positive
break;
}

I can tell you that the utility of this is very low, by the following argument.
Fortran once had a three-way arithmetic if statement for doing exactly the
above: taking one of three different actions based on a value being negative,
positive or zero. This statement had so little utility that it was marked
obsolescent and removed from Fortran.

So a better example than this one would have to be found.

Kaz Kylheku

unread,
Feb 16, 2009, 8:57:11 PM2/16/09
to
On 2009-02-14, Bartc <ba...@freeuk.com> wrote:
>
> "karthikbalaguru" <karthikb...@gmail.com> wrote in message
> news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...

>> 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.

The purpose of a switch statement isn't specifically to express a jump table
optimization, but simply to express the idea of branching on a code, whereby
the machine generates the implementation.

Jump table optimizations are possible only when the codes form consecutive
integer values (or values that can be mapped to consecutive integers by
removing a common displacement, and dividing by a common divisor).

When codes do not represent consecutive values, it is still possible to take
advantage of inequality comparisons to build a decision tree which optimizes
the switch. Such a tree would be tedious to build and maintain by hand.

And such a tree can be optimized further by making use of run-time statistical
data, which would be tedious to do by hand also.

A group of floating point values could be handled in that way.

But in actual numeric code, floating point numbers tend to be classified into
buckets, not into exact values.

The most useful form of a floating point switch statement would have to accept
ranges, using some new syntax.

This is because the cases that arise in numeric computing usually involve
ranges, and not distinct values.

switch (floating_value) {
case < -5.0:
// ...
break;
case [ -5.0, 0.0 ): // half open interval, including -5.0, excluding 0.
// ...
break;
case > 0.0: // or default:
// ...
break;
}

There would be constraints: none of the ranges can overlap, and when two ranges
share a boundary value, at least one of them must be open for that value.

This is analogous to the constraint that the cases in an integer switch must be
distinct.

The above syntax could be useful for integers too, as a way of condensing
cases. The syntax is straightforward: an optional inequality operator (>, <,
<=, or ==) followed by a constant (the absence of such an operator defaulting
to ==) or a range specification similar to the mathematical notation for
intervals: either [ or (, followed by a comma-separated pair of constants
(which undergo promotion and conversion to a common type) followed by ) or ].

There is value in the above construct in that it can optimize the
classification into ranges; the classification certainly doesn't have to
proceed by testing each of the ranges one by one.

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

Right. Taken care of by ranges.

>> Anyone working on including the support for floating
>> points w.r.t switch statements for the future release ?
>

> You will have a long wait.

More to the point, if you wait, nothing will happen.

A more proactive approach is to hack this into the GNU Compiler Collection (for
instance) to demonstrate its feasibility. Write some body of code which uses
the extensions (or better yet, sucker some other people into using them).

Kaz Kylheku

unread,
Feb 16, 2009, 9:12:25 PM2/16/09
to
On 2009-02-14, karthikbalaguru <karthikb...@gmail.com> wrote:
> Do you mean to say that C does not have facility for exact Floating
> Point

``exact'' and ``floating point'' are mutually exclusive terms, so
``exact floating point'' is an oxymoron.

C does not support oxymoronic numeric types. :)

Bartc

unread,
Feb 16, 2009, 9:25:30 PM2/16/09
to

"Kaz Kylheku" <kkyl...@gmail.com> wrote in message
news:200902231...@gmail.com...

> On 2009-02-14, karthikbalaguru <karthikb...@gmail.com> wrote:
>> Hi,
>>
>> Why does the switch case statement does not have support
>> for floating points ?

>> switch(a)
>> {


>> case 2.5:
>> printf("2.5 \n");
>> break;

> You need a better example to actually rationalize switching on floating

> point
> values. I.e. show some numerical code that benefits from a floating point
> switch statement.

> switch (copysign(1.0, x)) {


> case -1.0:
> // x is negative
> break;
> case 0:
> // x is zero
> break;
> case 1.0:
> // x is positive
> break;
> }
>
> I can tell you that the utility of this is very low, by the following
> argument.
> Fortran once had a three-way arithmetic if statement for doing exactly the
> above: taking one of three different actions based on a value being
> negative,
> positive or zero. This statement had so little utility that it was marked
> obsolescent and removed from Fortran.

Possibly because you can do a similar thing (to arithmetic IF) with a
Computed Goto.

There was a discussion on c.l.c perhaps a year ago on allowing /any/ type as
a switch index, and allowing non-constant case values. But the c.l.c lot
are a very conservative bunch who don't seem to like new syntax (or even
existing syntax a lot of the time). (Myself, I like interesting new bits of
syntax.)

One argument I think (possibly mine, can't remember) was that if the
language allows:

float x;
if (x==a)...
else if (x==b || x==c)...
else if (x==d)...
else e;

Then you might as well allow, in a switch or a new statement:

switch (x) {
case a:
case b: case c:
case d:
default e:

Whether using == on floating point values is a good idea, is irrelevant.
Another idea mooted was a case range operator ".." or "...", which to me
sounds ideal for floating point.

Again, the idea was shot down.

(Not that it would have made much difference; I'll be long dead before any
such changes would ever be widely available in C.)

--
Bartc

Bartc

unread,
Feb 16, 2009, 9:44:41 PM2/16/09
to

"Kaz Kylheku" <kkyl...@gmail.com> wrote in message
news:200902231...@gmail.com...
> On 2009-02-14, Bartc <ba...@freeuk.com> wrote:
>>
>> "karthikbalaguru" <karthikb...@gmail.com> wrote in message
>> news:1fbf2bf3-58f8-4727...@q30g2000prq.googlegroups.com...

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

>> 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.
>
> The purpose of a switch statement isn't specifically to express a jump
> table
> optimization, but simply to express the idea of branching on a code,
> whereby
> the machine generates the implementation.

>> There are also problems in exactly matching one floating point number

>> with
>> another; a special way of testing would be needed.
>
> Right. Taken care of by ranges.

I was trying to be impartial here, and just stating some probable facts. In
fact I quite like the idea.

>>> Anyone working on including the support for floating
>>> points w.r.t switch statements for the future release ?

>>
>> You will have a long wait.
>
> More to the point, if you wait, nothing will happen.
>
> A more proactive approach is to hack this into the GNU Compiler Collection
> (for
> instance) to demonstrate its feasibility. Write some body of code which
> uses
> the extensions (or better yet, sucker some other people into using them).

I was refering to the feature finding it's way -- and being widely
implemented -- in the next C standard.

--
Bartc

James Kuyper

unread,
Feb 17, 2009, 6:28:22 AM2/17/09
to
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>> James Kuyper wrote:
>>>> CBFalconer wrote:
>>>>
>>> ... snip ...
>>>>> 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.
>>> If you bother to read the portion you quoted, above, you may notice
>>> an example indicating why integers are needed.

You gave an example which, proves to you (though not to me) that
integers are needed. That example was based upon jump tables. You
accused me of failing to read that example. Yet my response to that
message directly refuted your argument about jump tables. That is the
basis for my conclusion, below, that you did not read my refutation.

>> Since I referred to the portion you underlined in my response, in the
>> course of refuting the idea that allowing jump tables makes integers a
>> necessity, I think you should have been able to concluded that I did in
>> fact read that portion.
>>
>> The fact that you did not reach that conclusion suggests to me that you
>> didn't bother reading the last paragraph of my response. Let me expand
>> on the counterargument that you apparently didn't notice. Let's assume
>> the following:
>
> The following is a copy of my original reply to you. It includes
> every word of your reply (as evidenced by the absence of <snip>
> markers). In that light, I cannot follow your 'did not read'
> comment. I answered the question you posed. I included an example
> showing why the standard was so written.

Oddly enough, the "did not read" comment was motivated by text that did
not appear anywhere in your original message, quoted below, but rather
in your later message, the one that I was directly replying to. That
might be why you couldn't find it?

...
>> What feature of the changes to the standard described in item 1)
>> would prevent an implementation from using a jump table to
>> implement the switch statement described in item 2?
>
> In a separate answer somewhere in this thread I gave an example of
> floating and integer representation of the number 3. Remember that

> the idea is to have rapid execution. ...

Allowing the controlling expression to have a floating point type would
not prevent use of a jump when a controlling expression with an integer
type is provided (assuming that the particular cases used are such as to
make a jump table a reasonable implementation approach).

> ... Any such intermixing of


> representation would require fairly extensive code to test and
> convert the representation, before indexing a pointer to a jump
> table with it. Or it would require two separate sets of code
> generated.

I presume that you mean that it would sometimes have to generate
something other than a jump table. Any decent compiler already does
that. Jump tables should only be used when they provide a better results
than other possible approaches, with "better" depending, among other
things, upon whether you're compiling for maximum speed or smallest
executable, or some other criterion entirely.

> ... Any such is contrary to the spirit of C, and totally


> unnecessary. At worst, avoidance requires anointing the switch
> statement with a cast.

I have no idea what that last comment refers to.

James Kuyper

unread,
Feb 17, 2009, 6:54:11 AM2/17/09
to
CBFalconer wrote:
> James Kuyper wrote:
> ... snip ...
>> My apologies for the confusion: that last sentence was supposed
>> to have the word "why" just before the word "does".
>>
> ... snip ...
>> The key issue with allowing floating point controlling expressions
>> is not whether it would be feasible to support them, but whether
>> it would be a good idea to encourage people to use them. Writing a
>> switch() statement with a floating point controlling expression
>> would be a bad idea, even if it were allowed, for precisely the
>> same reason it would be a bad idea to write the corresponding
>> series of if-else statements. That's because the conditions of the
>> corresponding if()'s would compare floating point values for
>> equality, a reasonable thing to do only in certain special cases.
>
> Among other things the present restrictions make it easy for the
> compiler to examine the set of switch values (they are all listed
> in the statement) ...

??? They would still all be listed in the statement. I don't see why
restricting it to an integer type would make it any easier to examine
that set than it would be if floating point types were allowed.

> ... and decide between generating if/else expressions


> or a jump table. That decision can result in major savings in code
> space and/or execution time.

As Keith has pointed out, a simplistic approach would be simply to not
bother checking whether a jump table would be an option, if the
controlling expression has a non-integral type.

> I'm glad you have identified the fundamental cause of our
> 'argument', which really doesn't exist. It shows how much
> difference one small missing word can cause.

Our argument was about whether or not the reason you gave was
sufficient. That we agree that a different reason is sufficient doesn't
change the fact that we still disagree about the your reason.

James Kuyper

unread,
Feb 17, 2009, 7:03:55 AM2/17/09
to
James Kuyper wrote:
...

> not appear anywhere in your original message, quoted below, but rather
[text which did not contain his original message]

My apologies; I decided to drop the redundant quotation of that message,
but forgot to remove the comment about it being "quoted below".

CBFalconer

unread,
Feb 17, 2009, 7:03:52 PM2/17/09
to
James Kuyper wrote:
>
... snip ...
>
>> ... Any such is contrary to the spirit of C, and totally
>> unnecessary. At worst, avoidance requires anointing the
>> switch statement with a cast.
>
> I have no idea what that last comment refers to.

switch ((int)float_value) {
case 0: whatever0(); break;
case 1: whatever1(); break;
default: break;
}

however (float_value == 0.9999999999) results in case 0. The cast
may generate considerable code.

James Kuyper

unread,
Feb 18, 2009, 6:43:28 AM2/18/09
to
CBFalconer wrote:
> James Kuyper wrote:
> ... snip ...
>>> ... Any such is contrary to the spirit of C, and totally
>>> unnecessary. At worst, avoidance requires anointing the
>>> switch statement with a cast.
>> I have no idea what that last comment refers to.
>
> switch ((int)float_value) {
> case 0: whatever0(); break;
> case 1: whatever1(); break;
> default: break;
> }
>
> however (float_value == 0.9999999999) results in case 0. The cast
> may generate considerable code.

Well, now I know what you're referring to, but I don't see the
relevance. If someone wants to write:

switch(float_value)
{
case 0.0: whatever0(); break;
case 1.0: whatever1(); break;
default: break;
}

They would presumably be very disappointed with any proposed replacement
which didn't have the same semantics as

if(float_value == 0.0)
whatever0();
else if(float_value == 1.0)
whatever1();

So in what way does this "avoidance" mechanism substitute for the
desired functionality?

The whole point of wanting to pass a floating point value to switch is
the desire for a cleaner way of expressing complicated code than a long
chain of if-else statements (ignoring the issues with floating point
comparisons for equality that apply to any such code).

In this particular case, the if-else chain looks simpler than the switch
statement. However, in more complicated situations, the switch()
statement would be clearer, if it were allowed, for precisely the same
reason that a switch() statement with an integral controlling expression
is sometimes clearer than the corresponding chain of if-else statements.

Such code should not be written in the first place, because of issues
about floating point comparisons for equality, but that's a different
issue from the one you've raised about jump tables.

CBFalconer

unread,
Feb 18, 2009, 8:06:14 PM2/18/09
to
James Kuyper wrote:
> CBFalconer wrote:
>
... snip ...
>
>> switch ((int)float_value) {
>> case 0: whatever0(); break;
>> case 1: whatever1(); break;
>> default: break;
>> }
>>
>> however (float_value == 0.9999999999) results in case 0. The
>> cast may generate considerable code.
>
> Well, now I know what you're referring to, but I don't see the
> relevance. If someone wants to write:
>
> switch(float_value) { /* code edited, cbf */

> case 0.0: whatever0(); break;
> case 1.0: whatever1(); break;
> default: break;
> }
>
> They would presumably be very disappointed with any proposed
> replacement which didn't have the same semantics as
>
> if (float_value == 0.0) whatever0();
> else if (float_value == 1.0) whatever1();

So, by eliminating the possibility, you eliminate the complaint.
>
... snip ...


>
> Such code should not be written in the first place, because of
> issues about floating point comparisons for equality, but that's
> a different issue from the one you've raised about jump tables.

Floating point is ALWAYS an approximation. You can never assume
the value is exact. For a case table you need exact values. Thus
to have the option of a case table you need exact values.

In addition, conversion between float and integer is not trivial.

Golden California Girls

unread,
Feb 19, 2009, 2:38:34 AM2/19/09
to
CBFalconer wrote:
>
> Floating point is ALWAYS an approximation.

??

> You can never assume the value is exact.

!!

ROTFLMAO!

So floating point values change all by themselves! How do those bits flip and
change value?

Chuck you are a riot. You should take your act on the road! You are even
better that Han.

> For a case table you need exact values. Thus
> to have the option of a case table you need exact values.

Floating point representations are exact. They don't change value all by
themselves.

I agree anyone is an idiot if they use equality comparison for the result of a
calculation with a floating point, but that doesn't make it inexact!

Gordon Burditt

unread,
Feb 19, 2009, 2:58:35 AM2/19/09
to
>> For a case table you need exact values. Thus
>> to have the option of a case table you need exact values.
>
>Floating point representations are exact.

There is no exact representation for many numbers people write in
binary floating point. When you write 0.1, you don't GET 0.1
exactly. It would require an infinite number of bits to do that.

>They don't change value all by
>themselves.
>
>I agree anyone is an idiot if they use equality comparison for the result of a
>calculation with a floating point, but that doesn't make it inexact!

Hardly any numbers with a decimal fraction can be exactly represented.
Exact integers can only be represented up to a point, depending on the
type.

The output of the following program on my machine is "not equal".
If you convert 0.1 to float and then back to double, it's no longer
equal to 0.1 put in a double in the first place.

#include <stdio.h>
int main(int argc, char **argv)
{
float f = 0.1;
double d = 0.1;

if (f == d) {
printf("equal\n");
} else {
printf("not equal\n");
}
return 0;
}

nick_keigh...@hotmail.com

unread,
Feb 19, 2009, 5:39:39 AM2/19/09
to
On 19 Feb, 07:58, gor...@hammy.burditt.org (Gordon Burditt) wrote:

> >Floating point representations are exact.  
>
> There is no exact representation for many numbers people write in
> binary floating point.  When you write 0.1, you don't GET 0.1
> exactly.  It would require an infinite number of bits to do that.

yes but
double d = 0.1;

has *an* exact value. It may not be 0.1 but it is exact


<snip>

James Kuyper

unread,
Feb 19, 2009, 6:28:05 AM2/19/09
to
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>
> ... snip ...
>>> switch ((int)float_value) {
>>> case 0: whatever0(); break;
>>> case 1: whatever1(); break;
>>> default: break;
>>> }
>>>
>>> however (float_value == 0.9999999999) results in case 0. The
>>> cast may generate considerable code.
>> Well, now I know what you're referring to, but I don't see the
>> relevance. If someone wants to write:
>>
>> switch(float_value) { /* code edited, cbf */
>> case 0.0: whatever0(); break;
>> case 1.0: whatever1(); break;
>> default: break;
>> }
>>
>> They would presumably be very disappointed with any proposed
>> replacement which didn't have the same semantics as
>>
>> if (float_value == 0.0) whatever0();
>> else if (float_value == 1.0) whatever1();
>
> So, by eliminating the possibility, you eliminate the complaint.

I'm not sure which possibility you're referring to. I'm not sure which
complaint you're referring to.

> ... snip ...
>> Such code should not be written in the first place, because of
>> issues about floating point comparisons for equality, but that's
>> a different issue from the one you've raised about jump tables.
>
> Floating point is ALWAYS an approximation.

Agreed - which is why I said "such code should not be written in the
first place".

> .. You can never assume
> the value is exact.

That depends upon the values involved, the code, and the implementation.
On most implementations I'm familiar with, sufficiently small integer
values (and "sufficiently small" includes some very large numbers)
divided by powers of 2.0 (negative powers included) can be relied upon
to be stored and compared exactly, assuming the number is within range
of the floating point type used. Also, if you do nothing with a floating
point value but move it around from one variable to another of the same
or greater precision, you can rely upon that value to be unchanged by
movement, and to compare to it's original value.

None of that's guaranteed by the standard, but I know of no reason why
it couldn't be; and it's sufficient to make exact comparison of floating
point values a reasonable thing to do, under some circumstances. Those
circumstances are sufficiently tricky to identify that it's a bad idea
to take advantage of them. That's the real reason why floating point
values should not be allowed as controlling expressions in switch()
statements. The feasibility (or lack thereof) of using a jump table to
implement such switch() statements is irrelevant, because there's no
need to use jump tables.

> ... For a case table you need exact values. Thus


> to have the option of a case table you need exact values.

Yes, but there's no need to generate a case table from a switch
statement; it's always possible to implement it as a chain of if-else
statements. Allowing floating point values to be used as a controlling
expression would do nothing to prevent generation of a case table when a
program contains a switch statement with a controlling expression of
integer type.

> In addition, conversion between float and integer is not trivial.

Neither is it rocket science. However, since there's no need to generate
case tables, an implementation that doesn't want to be bothered with
such a conversion need not even bother checking for the possibility that
a case table would be a legal way to implement a switch() statement, if
setting one up would require performing such a conversion.

Note: if the controlling expression of a switch() statement were allowed
to have a floating point type, and the values of the case expressions
happened to be such that they allowed efficient use of a jump table,
then the code generated by the compiler could NOT be equivalent to the
code you presented which I've quoted at the top of this message. That is
because doing so would produce incorrect behavior when the controlling
expression is not exactly equal to one of the case expressions, as
discussed above.

It would have to do something like the following (note that the goto
statements below are not proper C code; they are merely symbolic of what
the generated code does):

if(float_value >= min_case && float_value <= max_case)
{
int index = (int)floor((float_value - offset) / scale);

if(index * scale + offset == float_value)
goto jump_table[index];
}
goto default case;

Richard

unread,
Feb 19, 2009, 8:25:06 AM2/19/09
to
James Kuyper <james...@verizon.net> writes:

So a float which holds 2.0 is only an approximation?

Wow.

Kaz Kylheku

unread,
Feb 19, 2009, 12:41:40 PM2/19/09
to
On 2009-02-19, Golden California Girls <gldnc...@aol.com.mil> wrote:
>> For a case table you need exact values. Thus
>> to have the option of a case table you need exact values.
>
> Floating point representations are exact. They don't change value all by
> themselves.
>
> I agree anyone is an idiot if they use equality comparison for the result of a
> calculation with a floating point, but that doesn't make it inexact!

Chucky is right. Floating point representations are inexact. The fact that a
given floating point number is a rational number with a precisely determined
value doesn't change the fact that this floating-point number is an
approximation of some other number.

In the floating point representation, ranges of real numbers /alias/ to a
single floating point value. That's what makes it in exact.

So the value 1.0 not only represents the integer 1, but also the entire range
of real numbers from 1-epsilon to 1+epsilon, for some small epsilon.

Would you say that a sequence of digital samples are an exact representation
of the signal, because none of the bits are fuzzy?

Kaz Kylheku

unread,
Feb 19, 2009, 12:43:05 PM2/19/09
to
On 2009-02-19, Richard <rgr...@gmail.com> wrote:
> So a float which holds 2.0 is only an approximation?

Yes. It's an approximation of a range of real numbers near 2.0.

Golden California Girls

unread,
Feb 19, 2009, 12:45:05 PM2/19/09
to

Bingo!

Kaz Kylheku

unread,
Feb 19, 2009, 1:11:47 PM2/19/09
to
On 2009-02-19, Golden California Girls <gldnc...@aol.com.mil> wrote:

Yes, and similarly:

void compute_roots(struct polynomial *, double *roots);

will also return exact values! These may not in fact be the roots of the given
formula, but they are exact representations of whatever it is they represent.

So nothing in the computer can be inexact, in fact!

It's all exact ones and exact zeros!

You people are sheer geniuses.

Keith Thompson

unread,
Feb 19, 2009, 1:30:05 PM2/19/09
to
Kaz Kylheku <kkyl...@gmail.com> writes:
[...]

> Chucky is right. Floating point representations are inexact. The
> fact that a given floating point number is a rational number with a
> precisely determined value doesn't change the fact that this
> floating-point number is an approximation of some other number.
>
> In the floating point representation, ranges of real numbers /alias/
> to a single floating point value. That's what makes it in exact.
>
> So the value 1.0 not only represents the integer 1, but also the
> entire range of real numbers from 1-epsilon to 1+epsilon, for some
> small epsilon.

You're talking about the *meaning* of a given floating-point value.
Such a meaning can be defined only in the context of a given
application.

Here's a trivial program using the floating-point value 1.0:

#include <stdio.h>
int main(void)
{
double d = 1.0;
printf("d = %g\n", d);
return 0;
}

The double value 1.0 here doesn't represent a range of values.
It represents the exact mathematical value of one, and nothing else.
In particular, it doesn't represent any real value other than one
whose nearest double representation happens to be 1.0. In this
program, I can't represent (even an approximation of) 1+epsilon for
sufficiently small epsilon -- but that's ok, because the program
doesn't need to represent such values.

How do I know this? Because I wrote the program, and I get to say
what it means.

If I wanted to represent something other than one, I might use
a different representation; for example, I might add a flag that
indicates whether the stored value is exact or not. Or I might
change my mind and decide to let 1.0 represent some non-trivial
range of real values.

> Would you say that a sequence of digital samples are an exact
> representation of the signal, because none of the bits are fuzzy?

Certainly not. In such a context, the floating-point values are
inexact approximations of some real-world real values. In a different
context, though, I might be more interested in the single exact
mathematical real value represented by a given floating-point
representation.

The approximate view is more common, but it's not the only possible
view. And even in that view, how many of the bits are fuzzy? The
precision might be limited by the accuracy of the measuring instrument
rather than by the representation of the type. A stored value of 1.0
might represent anything in the range 0.995 to +1.005, depending on
how the value was generated and how I choose to interpret its meaning.

A given floating-point value can represent a range of values near the
exact stored value. That range might be larger or smaller depending
on the precision the measurements and computations that produced it.
And the range might consist of a single real value.

Bartc

unread,
Feb 19, 2009, 4:15:02 PM2/19/09
to

"Kaz Kylheku" <kkyl...@gmail.com> wrote in message
news:200902261...@gmail.com...

> On 2009-02-19, Richard <rgr...@gmail.com> wrote:
>> So a float which holds 2.0 is only an approximation?
>
> Yes. It's an approximation of a range of real numbers near 2.0.

So an integer 2 would be an approximation of the real numbers between 1.5
and 2.5?

--
Bartc

Golden California Girls

unread,
Feb 19, 2009, 6:58:10 PM2/19/09
to

Yes, we read the IEEE standard for floating point, understand base 2 math, took
a class in numeric analysis and understand about rational and irrational numbers.

IIRC the question being posited was if it was possible to have a case construct
that used a floating point switch. Chuck said no because floating point isn't
exact. He is being raked over the coals for that silliness. Floating point has
exact values and therefore you can make a case statement using a floating point
switch.

No one is saying that using equality comparisons with floating point numbers
that are results of calculations is a good idea.

Golden California Girls

unread,
Feb 19, 2009, 7:00:20 PM2/19/09
to

Not quite, you would have to exclude the limit of either 1.5 or 2.5, but
otherwise that is exactly what Kaz is saying.

Ben Bacarisse

unread,
Feb 19, 2009, 9:13:25 PM2/19/09
to

Why single out the reals? Why is 2.0 not an approximation to a region
of the complex plane? Why is 2 not an approximation of set of
surreal numbers? Any of that were not all daft enough, what is 'x' an
approximation of?

Whether a value in a C program is or is not approximate depends on the
intent of the programmer.

--
Ben.

Dik T. Winter

unread,
Feb 19, 2009, 9:54:34 PM2/19/09
to

Indeed! I have a good example where comparison for equality (not near
equality) in floating-point makes sense. In the calculation, using
Newtons method, of the square root of a floating-point number. For that
I did analyze the situation when arithmetic was truncating in the direction
of 0. In the range [1/4, 1] in general the algorithm would converge to a
single value (i.e. further iterates would give exactly the same value). So
a good stopping criterium would be exact equality of two results after
evaluation. In that range there were only *two* exceptions, and they can
easily be singled out before the calculation (again using exact equality).
Although C does not guarantee that it works, the underlying floating-point
arithmetic does guarantee it.

Long ago I have written a routine to compute the arcsine of an argument.
The routine heavily relied on exact comparisons, if they were not the result
would have been totally wrong for some inputs.

The conclusion is that you can do exact comparison on floating-point, but
you should know what you are doing. And that is in the realm of numerical
mathematics.
--
dik t. winter, cwi, science park 123, 1098 xg amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

CBFalconer

unread,
Feb 19, 2009, 11:16:04 PM2/19/09
to

I believe that for EPS = (pick one of) FLT_, DBL_, LDBL_EPSILON,
range will be:

2.0 + EPS > value > 2.0 - EPS

Golden California Girls

unread,
Feb 20, 2009, 12:24:02 AM2/20/09
to
CBFalconer wrote:
> Kaz Kylheku wrote:
>> Richard <rgr...@gmail.com> wrote:
>>
>>> So a float which holds 2.0 is only an approximation?
>> Yes. It's an approximation of a range of real numbers near 2.0.
>
> I believe that for EPS = (pick one of) FLT_, DBL_, LDBL_EPSILON,
> range will be:
>
> 2.0 + EPS > value > 2.0 - EPS

And you would be wrong -- AGAIN -- because it is base two math not base ten math.

Keith Thompson

unread,
Feb 20, 2009, 1:35:52 AM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> writes:

Can you explain what base ten math has to do with this? (Hint: As far
as I can tell, nothing.)

DBL_EPSILON, for example, is the difference between 1.0 and the least
value greater than 1.0 that's representable as a double. The next
representable number above 2.0 is very likely to be 2.0 + 2*DBL_EPSILON.
So for any mathematical real number between 2.0 and 2.0+DBL_EPSILON,
the nearest representable double value is 2.0.

On the other hand, the next representable number below 2.0 is likely
to be 2.0 - DBL_EPSILON, not 2.0 - 2*DBL_EPSILON. So the double value
2.0 can be seen as an approximation of any number in the range
2.0-DBL_EPSILON/2 .. 2.0+DBL_EPSILON.

Of course, that's only if you assume that a double value represents
any real value whose closest representation is that double value, and
as I've argued that's really a matter of what the code is intended to
do.

BTW, I've thought of another example where floating-point values can
be considered to be exact. If I recall correctly, stock prices used
to be quoted in eighths of a dollar, so a given stock might have a
current price of, say, $13.875). Any multiple of 1.0/8.0 within a
wide range can be represented exactly in double, assuming a typical
binary floating-point implementation. (The same is true for decimal
floating-point as well.) So if a stock program has a stored value of
13.875, that represents exactly $13.875, not an approximation of some
unspecified value between 13.875-8*DBL_EPSILON and
13.875+8*DBL_EPSILON. (IEEE 64-bit floating-point, which is typically
used to imlement double, gives exact values for multiples of 1/8 up to
about one quadrillion or so.)

Golden California Girls

unread,
Feb 20, 2009, 2:11:22 AM2/20/09
to
Keith Thompson wrote:
> Golden California Girls <gldnc...@aol.com.mil> writes:
>> CBFalconer wrote:
>>> Kaz Kylheku wrote:
>>>> Richard <rgr...@gmail.com> wrote:
>>>>
>>>>> So a float which holds 2.0 is only an approximation?
>>>> Yes. It's an approximation of a range of real numbers near 2.0.
>>> I believe that for EPS = (pick one of) FLT_, DBL_, LDBL_EPSILON,
>>> range will be:
>>>
>>> 2.0 + EPS > value > 2.0 - EPS
>> And you would be wrong -- AGAIN -- because it is base two math not
>> base ten math.
>
> Can you explain what base ten math has to do with this? (Hint: As far
> as I can tell, nothing.)

As you aren't CBF you aren't making the mistake I see in this NG all the time
with the epsilon value. That is scaling it base 10 and not base 2.

> DBL_EPSILON, for example, is the difference between 1.0 and the least
> value greater than 1.0 that's representable as a double. The next
> representable number above 2.0 is very likely to be 2.0 + 2*DBL_EPSILON.
> So for any mathematical real number between 2.0 and 2.0+DBL_EPSILON,
> the nearest representable double value is 2.0.

You are correct the next greater representable value is 2.0 + 2 times epsilon.
[you knew CBF's one times epsilon was wrong] (dropping double because it
doesn't matter if it is float, double or long double as long as you use the
corresponding epsilon) It isn't likely, it is required. You are incorrect in
your rounding statement about numbers between 2.0 and 2.0 + 2*epsilon. Rounding
down isn't right, round to nearest is.

> On the other hand, the next representable number below 2.0 is likely
> to be 2.0 - DBL_EPSILON, not 2.0 - 2*DBL_EPSILON. So the double value
> 2.0 can be seen as an approximation of any number in the range
> 2.0-DBL_EPSILON/2 .. 2.0+DBL_EPSILON.

This is also true, except you can not take the value 2.0 and subtract epsilon
and arrive at the next smaller representable value. 2.0 - epsilon will equal
2.0. This is so because of the base 2 exponent used in floating point values.
In changing epsilon so that it has the same base two exponent so the mantissa's
can be subtracted, you will make the mantissa of epsilon underflow and be zero.

Extra credit, how do you arrive with the next lower representable value below
2.0 knowing epsilon?

Phil Carmody

unread,
Feb 20, 2009, 2:19:13 AM2/20/09
to

And 2*2 would be an approximation of real numbers between 2.25 and 6.25?
Yikes! 2<<2 might be an approximation of some numbers that have half-set
bits! Where will this madness end?

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.

Phil Carmody

unread,
Feb 20, 2009, 2:25:19 AM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> writes:

You're just as wrong. The issue is completely orthogonal to the choice
of radix. Go read some Goldberg or Kahan (or Knuth, or ...).

Keith Thompson

unread,
Feb 20, 2009, 4:09:33 AM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> writes:
> Keith Thompson wrote:
>> Golden California Girls <gldnc...@aol.com.mil> writes:
>>> CBFalconer wrote:
>>>> Kaz Kylheku wrote:
>>>>> Richard <rgr...@gmail.com> wrote:
>>>>>> So a float which holds 2.0 is only an approximation?
>>>>> Yes. It's an approximation of a range of real numbers near 2.0.
>>>> I believe that for EPS = (pick one of) FLT_, DBL_, LDBL_EPSILON,
>>>> range will be:
>>>>
>>>> 2.0 + EPS > value > 2.0 - EPS
>>> And you would be wrong -- AGAIN -- because it is base two math not
>>> base ten math.
>>
>> Can you explain what base ten math has to do with this? (Hint: As far
>> as I can tell, nothing.)
>
> As you aren't CBF you aren't making the mistake I see in this NG all
> the time with the epsilon value. That is scaling it base 10 and not
> base 2.

Whatever mistake you're talking about, neither I nor CBF made it.
You're the only one talking about base ten; the range CBF specified
(2.0 + EPS > value > 2.0 - EPS) has nothin to do with base ten.

>> DBL_EPSILON, for example, is the difference between 1.0 and the least
>> value greater than 1.0 that's representable as a double. The next
>> representable number above 2.0 is very likely to be 2.0 + 2*DBL_EPSILON.
>> So for any mathematical real number between 2.0 and 2.0+DBL_EPSILON,
>> the nearest representable double value is 2.0.
>
> You are correct the next greater representable value is 2.0 + 2
> times epsilon. [you knew CBF's one times epsilon was wrong]
> (dropping double because it doesn't matter if it is float, double or
> long double as long as you use the corresponding epsilon)

I merely used double as a concrete example.

> It isn't
> likely, it is required.

Required by what? The IEC 60559 floating-point standard (commonly
called IEEE) probably does require it, but the C standard doesn't.
At least one IBM mainframe floating-point format uses exponents
representing powers of 16, so the granularity would jump by a factor
of 16 rather than 2; DBL_EPSILON would be the difference between
any number and the next larger representable number over the range
1.0 <= X < 16.0 (I think).

> You are incorrect in your rounding
> statement about numbers between 2.0 and 2.0 + 2*epsilon. Rounding
> down isn't right, round to nearest is.

Read what I wrote again; I assumed round-to-nearest; I just didn't
mention values less than 2.0. But again, the C standard doesn't
require round-to-nearest; for an implementation that doesn't claim IEC
60559 conformance, C places very few constraints on floating-point
behavior.

>> On the other hand, the next representable number below 2.0 is likely
>> to be 2.0 - DBL_EPSILON, not 2.0 - 2*DBL_EPSILON. So the double value
>> 2.0 can be seen as an approximation of any number in the range
>> 2.0-DBL_EPSILON/2 .. 2.0+DBL_EPSILON.
>
> This is also true, except you can not take the value 2.0 and
> subtract epsilon and arrive at the next smaller representable value.
> 2.0 - epsilon will equal 2.0. This is so because of the base 2
> exponent used in floating point values. In changing epsilon so that
> it has the same base two exponent so the mantissa's can be
> subtracted, you will make the mantissa of epsilon underflow and be
> zero.

Oh? Then why does this program:

#include <stdio.h>
#include <float.h>
int main(void)
{
double below = 2.0 - DBL_EPSILON;
double two = 2.0;
double above = 2.0 + DBL_EPSILON * 2;

printf("below = %.30f\n", below);
printf("two = %.30f\n", two);
printf("above = %.30f\n", above);
return 0;
}

produce this output?

below = 1.999999999999999777955395074969
two = 2.000000000000000000000000000000
above = 2.000000000000000444089209850063

> Extra credit, how do you arrive with the next lower representable
> value below 2.0 knowing epsilon?

If you don't know what floating-point model is being used, you can't;
knowing epsilon is insufficient given what the C standard guarantees
If you happen to know the system uses IEC 60559 floating-point, just
subtract epsilon.

DBL_EPSILON is the difference between 1.0 and the next higher
representable number. It's the granularity of the representation for
the value 1.0 and a range of values above 1.0. Assuming a binary
exponent, the exponent, and therefore the granularity of the mantissa,
will be the same for 1.0 <= X < 2.0. When we reach 2.0, the exponent
increases by 1 and the granularity becomes coarser by a factor of 2.
The same thing happens when we reach 4.0, and each power of 2.0 after
that. So the consecutive representable numbers are:

...
1.0-EPS/2
1.0-EPS
1.0
1.0+EPS
1.0+EPS*2
...
2.0-EPS*2
2.0-EPS
2.0
2.0+EPS*2
2.0+EPS*4
...
4.0-EPS*4
4.0-EPS*2
4.0-EPS
4.0-EPS*4
4.0-EPS*8
...

Ike Naar

unread,
Feb 20, 2009, 4:17:04 AM2/20/09
to
In article <uIsnl.535$tw4...@nwrddc01.gnilink.net>,

Golden California Girls <gldnc...@aol.com.mil> wrote:
>This is also true, except you can not take the value 2.0 and subtract epsilon
>and arrive at the next smaller representable value. 2.0 - epsilon will equal
>2.0. This is so because of the base 2 exponent used in floating point values.
>In changing epsilon so that it has the same base two exponent so the mantissa's
>can be subtracted, you will make the mantissa of epsilon underflow and be zero.

On this old x86, with gcc 2.95.3, 2.0f - FLT_EPSILON _does_ yield
the next smaller representable float value below 2.0f .

expression value representation

1.0f-FLT_EPSILON 0.9999998808 0x3f7ffffe
1.0f 1.0000000000 0x3f800000
1.0f+FLT_EPSILON 1.0000001192 0x3f800001

2.0f-2*FLT_EPSILON 1.9999997616 0x3ffffffe
2.0f-FLT_EPSILON 1.9999998808 0x3fffffff
2.0f 2.0000000000 0x40000000
2.0f+FLT_EPSILON 2.0000000000 0x40000000
2.0f+2*FLT_EPSILON 2.0000002384 0x40000001

Exactly the same results appear on a Sun SPARC, with Sun CC.

>Extra credit, how do you arrive with the next lower representable value below
>2.0 knowing epsilon?

Thanks for the extra credit.

Golden California Girls

unread,
Feb 20, 2009, 9:59:41 AM2/20/09
to

What is the value of FLT_EVAL_METHOD on your system? It doesn't work to do long
double math with FLT_EPSILON.

Golden California Girls

unread,
Feb 20, 2009, 11:48:44 AM2/20/09
to
Keith Thompson wrote:
> Golden California Girls <gldnc...@aol.com.mil> writes:
>> Keith Thompson wrote:
>> It isn't
>> likely, it is required.
>
> Required by what? The IEC 60559 floating-point standard (commonly
> called IEEE) probably does require it, but the C standard doesn't.

I do see that C doesn't require much of anything for floating math.

> At least one IBM mainframe floating-point format uses exponents
> representing powers of 16, so the granularity would jump by a factor
> of 16 rather than 2; DBL_EPSILON would be the difference between
> any number and the next larger representable number over the range
> 1.0 <= X < 16.0 (I think).

Correct.

> But again, the C standard doesn't
> require round-to-nearest; for an implementation that doesn't claim IEC
> 60559 conformance, C places very few constraints on floating-point
> behavior.

It does seem to permit useless floating point.

What is the value of FLT_EVAL_METHOD? Or put another way have you been lied to
about the value of DBL_EPSILON for computations.

>> Extra credit, how do you arrive with the next lower representable
>> value below 2.0 knowing epsilon?
>
> If you don't know what floating-point model is being used, you can't;
> knowing epsilon is insufficient given what the C standard guarantees

Correct.

> If you happen to know the system uses IEC 60559 floating-point, just
> subtract epsilon.

In real math.

Very true.

Lets take a 2 bit mantissa and count up. Our value of epsilon is then 1/2.

decimal mantissa exponent
0.5 10 -1
0.75 11 -1
1.0 10 0
1.5 11 0
2.0 10 1
3.0 11 1
4.0 10 10
6.0 11 10

Now lets take 2.0 and subtract our epsilon of 0.5

2.0 10 1
0.5 10 -1
but we can't subtract the mantissa's until the exponents match.
we shift and get
2.0 10 1
0.5 00 1
now we perform the subtraction and get
2.0 10 1

I thought you said you could take 2.0 and subtract epsilon and get the next
lowest number? The C standard does not.

What happens in your case then? It had to use a wider mantissa!
2.0 100 1
0.5 001 1
now we perform the subtraction and get
1.5 011 1
It normalized and did FLT_ROUNDS
1.5 11 0
It used at least a 3 bit wide mantissa. But the epsilon value for a 3 bit wide
mantissa isn't 0.5 but 0.25. You've been lied to. Not really, just given
misleading information. On your implementation FLT_EVAL_METHOD isn't 0 or 1, it
must be 2 or a negative number.

And the above is why I dropped double and said use the appropriate epsilon.

AH, the fun of the C un-standard!

BTW to get the next lower representable value below 2.0 on a implementation with
FLT_EVAL_METHOD 0, subtract 2.0 * epsilon from 2.0 and then add epsilon,
assuming binary mantissa and exponent.

Keith Thompson

unread,
Feb 20, 2009, 12:58:22 PM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> writes:
> Keith Thompson wrote:
>> Golden California Girls <gldnc...@aol.com.mil> writes:
>>> Keith Thompson wrote:
>>> It isn't
>>> likely, it is required.
>>
>> Required by what? The IEC 60559 floating-point standard (commonly
>> called IEEE) probably does require it, but the C standard doesn't.
>
> I do see that C doesn't require much of anything for floating math.
>
>> At least one IBM mainframe floating-point format uses exponents
>> representing powers of 16, so the granularity would jump by a factor
>> of 16 rather than 2; DBL_EPSILON would be the difference between
>> any number and the next larger representable number over the range
>> 1.0 <= X < 16.0 (I think).
>
> Correct.
>
>> But again, the C standard doesn't
>> require round-to-nearest; for an implementation that doesn't claim IEC
>> 60559 conformance, C places very few constraints on floating-point
>> behavior.
>
> It does seem to permit useless floating point.

It permits a wide variety of floating-point implementations, because
there are a wide variety of floating-point implementations in the real
world, and declaring most such implementations non-conforming likely
would have killed the C language.

Now C *could* have defined a set of conditions looser than what's in
IEC 60559 while still guaranteeing that, for example, 1.0+1.0==2.0 and
being consistent with all the real-world implementations. (The Ada
standard does something like this.) But the authors chose instead
just to rely on the implementations to do the right thing -- which, in
most cases, they do.

2, which means to "evaluate all operations and constants to the range
and precision of the long double type", but I don't think that's
relevant.

> Or put another way have you
> been lied to about the value of DBL_EPSILON for computations.

No.

I just modified the above program to use long double rather than
double and got similar results, so the result don't depend on using a
wider type for calculations.

I computed the value of 2.0 - DBL_EPSILON. Both operands are exactly
representable values of type double. I stored the result, whose
mathematical value is also exactly representable in type double, in an
object of type double. Assuming a sane floating-point implementation,
or more specifically an IEC 60559 floating-point representation, I can
expect the exact mathematical result to be stored in the object.

[...]

> Lets take a 2 bit mantissa and count up. Our value of epsilon is then 1/2.
>
> decimal mantissa exponent
> 0.5 10 -1
> 0.75 11 -1
> 1.0 10 0
> 1.5 11 0
> 2.0 10 1
> 3.0 11 1
> 4.0 10 10
> 6.0 11 10
>
> Now lets take 2.0 and subtract our epsilon of 0.5
>
> 2.0 10 1
> 0.5 10 -1
> but we can't subtract the mantissa's until the exponents match.
> we shift and get
> 2.0 10 1
> 0.5 00 1
> now we perform the subtraction and get
> 2.0 10 1

2.0, 0.5, and 1.5 are all exactly representable in this floating-point
representation, so computing 2.0 - 0.5 should give me 1.5 in any sane
implementation. If you make assumptions about how the subtraction is
implemented (shifting mantissas and tweaking exponents, keeping
everything within your representation at all times), then you might
conclude that the calculation yields 2.0. Conclusion: your
assumptions are incorrect.

FLT_EVAL_METHOD refers to results of C floating-point operations such
as ordinary subtraction. What you're talking about is intermediate
results that occur during the execution of that subtraction operation,
probably within the machine's floating-point unit. As I understand
it, FPUs do have to use extra bits internally to get correct results.

The only thing that's visible to a C program is that if you compute
x = y - z;
where y, z, and the mathematical result of the subtraction are all
exactly representable in the given type, you'll get the right result
stored in x. (Again, the C standard doesn't require this, but IEC
60559 does.) What happens *within* the subtraction operation,
whatever magic the FPU performs to get the right answer, is outside
the scope of the language and, I suggest, of this discussion; all
that's relevant is that subtraction *works*.

> I thought you said you could take 2.0 and subtract epsilon and get the next
> lowest number? The C standard does not.

Right, I should have stated more clearly that I was assuming an IEC
60559 implementation.

[...]

> AH, the fun of the C un-standard!

I don't know what that's supposed to mean. The C standard leaves a
lot of floating-point issues unspecified because it has to, because
there are so many different floating-point implementations in the real
world. But C allows an implementation to claim IEC 60559 conformance,
and for such an implementation the results are reasonably well
defined.

> BTW to get the next lower representable value below 2.0 on a
> implementation with FLT_EVAL_METHOD 0, subtract 2.0 * epsilon from
> 2.0 and then add epsilon, assuming binary mantissa and exponent.

Or just subtract epsilon from 2.0 and let the FPU (or whatever the
system uses for floating-point computations) worry about using however
many extra bits it needs to get the write answer. I challenge you to
show me a system where that doesn't work, for any C floating-point
type you choose. (C doesn't forbid such a system, but I doubt that
you can find any in existence.)

Golden California Girls

unread,
Feb 20, 2009, 4:23:43 PM2/20/09
to
Keith Thompson wrote:
> Golden California Girls <gldnc...@aol.com.mil> writes:
>> Keith Thompson wrote:
>> What is the value of FLT_EVAL_METHOD?
>
> 2, which means to "evaluate all operations and constants to the range
> and precision of the long double type", but I don't think that's
> relevant.
>
>[snip]

> FLT_EVAL_METHOD refers to results of C floating-point operations such
> as ordinary subtraction. What you're talking about is intermediate
> results that occur during the execution of that subtraction operation,
> probably within the machine's floating-point unit. As I understand
> it, FPUs do have to use extra bits internally to get correct results.

I believe that is why the C standard has a FLT_EVAL_METHOD "-1 indeterminable"
Unless of course there is some confusion over the meaning of "all" and
"operations" in "all operations."

>> BTW to get the next lower representable value below 2.0 on a
>> implementation with FLT_EVAL_METHOD 0, subtract 2.0 * epsilon from
>> 2.0 and then add epsilon, assuming binary mantissa and exponent.
>
> Or just subtract epsilon from 2.0 and let the FPU (or whatever the
> system uses for floating-point computations) worry about using however
> many extra bits it needs to get the write answer. I challenge you to
> show me a system where that doesn't work, for any C floating-point
> type you choose. (C doesn't forbid such a system, but I doubt that
> you can find any in existence.)

Why don't you do the opposite and prove there aren't any that do? To make your
search faster, start with chips that don't have FPU's and the floating point is
done in software.

Keith Thompson

unread,
Feb 20, 2009, 4:57:19 PM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> writes:
> Keith Thompson wrote:
>> Golden California Girls <gldnc...@aol.com.mil> writes:
>>> Keith Thompson wrote:
>>> What is the value of FLT_EVAL_METHOD?
>>
>> 2, which means to "evaluate all operations and constants to the range
>> and precision of the long double type", but I don't think that's
>> relevant.
>>
>>[snip]
>> FLT_EVAL_METHOD refers to results of C floating-point operations such
>> as ordinary subtraction. What you're talking about is intermediate
>> results that occur during the execution of that subtraction operation,
>> probably within the machine's floating-point unit. As I understand
>> it, FPUs do have to use extra bits internally to get correct results.
>
> I believe that is why the C standard has a FLT_EVAL_METHOD "-1
> indeterminable" Unless of course there is some confusion over the
> meaning of "all" and "operations" in "all operations."

I think there is some confusion there, and I don't think it's mine.
If an operation such as the subtraction in (2.0 - DBL_EPSILON) needs
to use extra bits *within the FPU* to produce a correct double result,
that's just part of the way the double operation is performed; it's
not performing the operation in type long double.

In other words, whatever goes on inside the implementation of "-"
isn't an "operation" as far as the standard is concerned; only the
entire "-" is an "operation".

But even if FLT_EVAL_METHOD == 2, I think you'll find that
2.0L - LDBL_EPSILON < 2.0L
though the C standard doesn't require this.

Here's another program:

#include <stdio.h>
#include <float.h>
int main(void)
{

long double below = 2.0L - LDBL_EPSILON;
long double two = 2.0L;
printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
if (below < two && two - below == LDBL_EPSILON) {
puts("Yes");
}
else {
puts("No");
}
return 0;
}

All calculations are done in long double, so the value of
FLT_EVAL_METHOD is irrelevant (unless perhaps it's negative).

>>> BTW to get the next lower representable value below 2.0 on a
>>> implementation with FLT_EVAL_METHOD 0, subtract 2.0 * epsilon from
>>> 2.0 and then add epsilon, assuming binary mantissa and exponent.
>>
>> Or just subtract epsilon from 2.0 and let the FPU (or whatever the
>> system uses for floating-point computations) worry about using however
>> many extra bits it needs to get the write answer. I challenge you to
>> show me a system where that doesn't work, for any C floating-point
>> type you choose. (C doesn't forbid such a system, but I doubt that
>> you can find any in existence.)
>
> Why don't you do the opposite and prove there aren't any that do?
> To make your search faster, start with chips that don't have FPU's
> and the floating point is done in software.

I'm not sure that I have access to any such systems, and if I do, I'm
not going to spend the time trying to prove a negative.

You're claiming that the trick of subtracting 2.0*epsilon from 2.0 and
then adding epsilon is necessary. I claim that it isn't, at least on
typical implementations with sane floating-point support. (The C
standard doesn't require sanity in the sense that I'm using the word;
IEC 60559 requires sanity and more.) There may well be systems with,
for example, software floating-point where this fails -- but it's
quite likely that the authors of software FP implementations have gone
to the trouble of getting this right. And I believe (though I haven't
checked) that IEC 60559 *requires* the program to print "Yes".

So here's my new challenge. Find a C implementation where the above
program compiles and prints "No". You might have to specify C99
compliance to make FLT_EVAL_METHOD visible; feel free to comment out
that line if you need to.

Richard Bos

unread,
Feb 20, 2009, 6:37:47 PM2/20/09
to
Golden California Girls <gldnc...@aol.com.mil> wrote:

> Kaz Kylheku wrote:
> > It's all exact ones and exact zeros!
> >
> > You people are sheer geniuses.
>
> Yes, we read the IEEE standard for floating point, understand base 2 math, took
> a class in numeric analysis and understand about rational and irrational numbers.
>
> IIRC the question being posited was if it was possible to have a case construct
> that used a floating point switch.

No, it wasn't. The underlying question was not whether it was possible -
it's _possible_ to have a case statements which uses strings - but
whether it is worth the trouble.

> No one is saying that using equality comparisons with floating point numbers
> that are results of calculations is a good idea.

Actually, yes. By asking for a case statement using FPNs, some people
are doing exactly that.

Richard

Ike Naar

unread,
Feb 20, 2009, 7:32:50 PM2/20/09
to
In article <xzznl.559$tw4...@nwrddc01.gnilink.net>,

Golden California Girls <gldnc...@aol.com.mil> wrote:
>Ike Naar wrote:
>> On this old x86, with gcc 2.95.3, 2.0f - FLT_EPSILON _does_ yield
>> the next smaller representable float value below 2.0f .
>>
>> expression value representation
>>
>> 1.0f-FLT_EPSILON 0.9999998808 0x3f7ffffe
>> 1.0f 1.0000000000 0x3f800000
>> 1.0f+FLT_EPSILON 1.0000001192 0x3f800001
>>
>> 2.0f-2*FLT_EPSILON 1.9999997616 0x3ffffffe
>> 2.0f-FLT_EPSILON 1.9999998808 0x3fffffff
>> 2.0f 2.0000000000 0x40000000
>> 2.0f+FLT_EPSILON 2.0000000000 0x40000000
>> 2.0f+2*FLT_EPSILON 2.0000002384 0x40000001
>>
>> Exactly the same results appear on a Sun SPARC, with Sun CC.
>>
>What is the value of FLT_EVAL_METHOD on your system?
>It doesn't work to do long double math with FLT_EPSILON.

On the x86 (OS is OpenBSD 3.3), FLT_EVAL_METHOD is not defined.
On the Sun, FLT_EVAL_METHOD is 0 .

0 new messages