The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Equality failure in <=.
 There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic. There was an error processing your request. Please try again. Standard view   View as tree
 18 messages

From:
To:
Cc:
Followup To:
Subject:
 Validation: For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon.

More options Mar 24 2010, 4:03 pm
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Wed, 24 Mar 2010 13:03:39 -0700
Local: Wed, Mar 24 2010 4:03 pm
Subject: Equality failure in <=.

Oh, and I see another bug in the output of my
celsius-to-fahrenheit converer program, that I posted about
here a few minutes ago (re. extra blank lines form printf).

Again, the main lines are:

printf("    Cels        Fahr   \n");

for (Cels = CelsMin; Cels <= CelsMax; Cels += CelsInc)
{
Fahr = (((Cels*180.0)/100.0)+32);
printf("%10.3f   %10.3f\n\n", Cels, Fahr);
}

and the output for "celsfahr 40 41 0.001" is (sans extra blank lines):

Cels        Fahr
40.000      104.000
40.200      104.360
40.400      104.720
40.600      105.080
40.800      105.440

Where is 41.000 ???  This table should have 6 entries, not 5,
and the last line should read:

41.000      105.800

Looks like the <= comparison is failing when Cels gets up to 41.000.
I'm guessing it's somehow gets off a very small amount.  Perhaps
it's 41.00000001 when it gets compared to 41, so <= return false.

I could change "Cels <= CelsMax" to "Cels <= (CelsMax+0.0001)".
But that's a bit ugly.  Any simpler way to do this?

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 4:18 pm
Newsgroups: comp.lang.c
Date: Wed, 24 Mar 2010 20:18:40 +0000
Local: Wed, Mar 24 2010 4:18 pm
Subject: Re: Equality failure in <=.

Yes - count up in integers and work out the floating point values for
printing.  But if ugly concerns you, look at those variable names,
capitalisation conventions and our long recent thread on testing
integers to see if they still equal variables.
--
Online waterways route planner            | http://canalplan.eu
Plan trips, see photos, check facilities  | http://canalplan.org.uk

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 4:59 pm
Newsgroups: comp.lang.c
From: Eric Sosman <esos...@ieee-dot-org.invalid>
Date: Wed, 24 Mar 2010 16:59:15 -0400
Local: Wed, Mar 24 2010 4:59 pm
Subject: Re: Equality failure in <=.
On 3/24/2010 4:03 PM, Robbie Hatley wrote:

> Oh, and I see another bug in the output of my
> celsius-to-fahrenheit converer program, that I posted about
> here a few minutes ago (re. extra blank lines form printf).

> Again, the main lines are:

>     printf("    Cels        Fahr   \n");

>     for (Cels = CelsMin; Cels<= CelsMax; Cels += CelsInc)
>     {
>        Fahr = (((Cels*180.0)/100.0)+32);
>        printf("%10.3f   %10.3f\n\n", Cels, Fahr);

Note the two count them 2 count them again II zwei due
deux newline characters ...  You asked for blank lines, you
got blank lines -- well, duh.

>     }

> and the output for "celsfahr 40 41 0.001" is (sans extra blank lines):

>      Cels        Fahr
>      40.000      104.000
>      40.200      104.360
>      40.400      104.720
>      40.600      105.080
>      40.800      105.440

> Where is 41.000 ???  This table should have 6 entries,[...]

In light of the 0.001 increment, I'd have expected about
a thousand lines.  So I guess `+=' is also broken, huh?

--
Eric Sosman
esos...@ieee-dot-org.invalid

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 5:08 pm
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Wed, 24 Mar 2010 14:08:04 -0700
Local: Wed, Mar 24 2010 5:08 pm
Subject: Re: Equality failure in <=.

"Nick" wrote:
> ... count up in integers and work out the floating point values for
> printing...

Ok, could do that.  In other programs.
In these two, I'm feeling lazy.
Just got them to work using the "+0.0001" thing.
I admit that the "integer" thing sounds like the technically
better way of doing it.

> ... look at those variable names ...

Hey, at least I didn't name them:

int a,b,c,d,e,f;

I've known programmers that do that.  In production code,
for mid-sized corporations, no less.  Grrr!

> ... capitalisation conventions ...

For some reason, Piers Anthony comes to mind.  I see a flock
of birds, each shaped like a small letter c, rising from
the ground in front of me.  I step back, startled, but my
programmer friend beside me says, "don't be alarmed, it's only
a flock of small C-gulls on their way to a Capitalization
Convention".

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 6:12 pm
Newsgroups: comp.lang.c
From: Seebs <usenet-nos...@seebs.net>
Date: 24 Mar 2010 22:12:12 GMT
Local: Wed, Mar 24 2010 6:12 pm
Subject: Re: Equality failure in <=.
On 2010-03-24, Robbie Hatley <see.my.signat...@for.my.contact.info> wrote:

> Oh, and I see another bug in the output of my
> celsius-to-fahrenheit converer program, that I posted about
> here a few minutes ago (re. extra blank lines form printf).

No, you don't.  :)

>    for (Cels = CelsMin; Cels <= CelsMax; Cels += CelsInc)
>    {
>       Fahr = (((Cels*180.0)/100.0)+32);
>       printf("%10.3f   %10.3f\n\n", Cels, Fahr);
>    }
>     41.000      105.800
> Looks like the <= comparison is failing when Cels gets up to 41.000.
> I'm guessing it's somehow gets off a very small amount.  Perhaps
> it's 41.00000001 when it gets compared to 41, so <= return false.

Right.

> I could change "Cels <= CelsMax" to "Cels <= (CelsMax+0.0001)".
> But that's a bit ugly.  Any simpler way to do this?

It's surprisingly hard.  Basically, floating point numbers generally
can't represent values that aren't exact multiples of a power of two.
"0.2" is not exact, so addition of "0.2" repeatedly is also not exact.

If you really need to do this, do all the loop controls in integer math,
then convert at the last minute using a fixed scale factor.  e.g.,
loop up to 205, then divide by 5 inside the loop.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nos...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 6:26 pm
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Wed, 24 Mar 2010 15:26:10 -0700
Local: Wed, Mar 24 2010 6:26 pm
Subject: Re: Equality failure in <=.

"Eric Sosman" wrote:
> ...
> Robbie wrote:
> > ...
> >    printf("%10.3f   %10.3f\n\n", Cels, Fahr);
> > ...

> Note the two count them 2 count them again II zwei due
> deux newline characters ...  You asked for blank lines, you
> got blank lines -- well, duh.

Yep, that time I quoted correct source.  (See my post,
"Oops, wrong source file!".)  That problem solved.

> > ... and the output for "celsfahr 40 41 0.001" is ...

> >      Cels        Fahr
> >      40.000      104.000
> >      40.200      104.360
> >      40.400      104.720
> >      40.600      105.080
> >      40.800      105.440

> > Where is 41.000 ???  This table should have 6 entries ...

> In light of the 0.001 increment, I'd have expected about
> a thousand lines.  So I guess `+=' is also broken, huh?

That was a typo in my post.  I should have typed,
"celsfahr 40 41 0.2".  Dunno why I wrote 0.001.  That's the
minimum increment the program allows, so I probably had
that on my mind.

The <= issue is also now fixed.  I used a +0.0001 "fuzz zone".
(See other post.)

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 8:04 pm
Newsgroups: comp.lang.c
From: Phil Carmody <thefatphil_demun...@yahoo.co.uk>
Date: Thu, 25 Mar 2010 02:04:52 +0200
Local: Wed, Mar 24 2010 8:04 pm
Subject: Re: Equality failure in <=.

/What Every Computer Scientist Should Know About Floating-Point Arithmetic/
by David Goldberg

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 24 2010, 8:41 pm
Newsgroups: comp.lang.c
From: Eric Sosman <esos...@ieee-dot-org.invalid>
Date: Wed, 24 Mar 2010 20:41:47 -0400
Local: Wed, Mar 24 2010 8:41 pm
Subject: Re: Equality failure in <=.
On 3/24/2010 6:26 PM, Robbie Hatley wrote:

> "Eric Sosman" wrote:
>> Robbie wrote:

>>> Where is 41.000 ???  This table should have 6 entries ...

>> In light of the 0.001 increment, I'd have expected about
>> a thousand lines.  So I guess `+=' is also broken, huh?

> That was a typo in my post.  I should have typed,
> "celsfahr 40 41 0.2".  Dunno why I wrote 0.001.  That's the
> minimum increment the program allows, so I probably had
> that on my mind.

Based on a large study (sample size N=2), there's some
indication that you find it difficult to make an accurate
problem report.  You might want to think about ways of improving
your accuracy, as there are situations where an inaccurate
report can be life-threatening.  "Doctor, I have this terrible
pain in the diodes on my left side."  "Nothing to worry about,
Robbie, just take two aspirin and call me in the morning.  If
you'd said the *right* side, I'd have been seriously worried --
but on the left, I'm quite sure it's nothing to fret about.
Have a nice life!"

> The<= issue is also now fixed.  I used a +0.0001 "fuzz zone".
> (See other post.)

Yeah.  As others have explained, this is not a good solution.
code," I'm a little disturbed that you didn't know this already.
No offense meant: We all start out ignorant.  But preserving one's
ignorance is not a virtue, and if you're dealing with "production

--
Eric Sosman
esos...@ieee-dot-org.invalid

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 12:19 am
Newsgroups: comp.lang.c
From: Keith Thompson <ks...@mib.org>
Date: Wed, 24 Mar 2010 21:19:33 -0700
Local: Thurs, Mar 25 2010 12:19 am
Subject: Re: Equality failure in <=.

0.001 should be 0.2, yes?

>     Cels        Fahr
>     40.000      104.000
>     40.200      104.360
>     40.400      104.720
>     40.600      105.080
>     40.800      105.440

> Where is 41.000 ???  This table should have 6 entries, not 5,
> and the last line should read:

>     41.000      105.800

[...]

In addition to the other advice you've gotten, it might be instructive
to print the values to greater precision.  Since you stated a new
more effort than I'm willing to expend.  But here's a program based on
the snipped above, which allows you to vary the precision of the
output via a command-line argument.  Try it with increasing values of
"digits".  On my system, things start to get interesting around
digits==14.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
const double CelsMin = 40.0;
const double CelsMax = 41.0;
const double CelsInc = 0.2;
double Cels;
double Fahr;
int digits;

if (argc >= 2) {
digits = atoi(argv[1]); /* crude, but ok for now */
}
else {
digits = 2;
}

printf("CelsMin = %.*f\n", digits, CelsMin);
printf("CelsMax = %.*f\n", digits, CelsMax);
printf("CelsInc = %.*f\n", digits, CelsInc);

for (Cels = CelsMin; Cels <= CelsMax; Cels += CelsInc) {
Fahr = Cels * 180.0 / 100.0 + 32.0;
printf("Cels = %.*f  Fahr = %.*f\n",
digits, Cels, digits, Fahr);
}
printf("After loop, Cels = %.*f\n", digits, Cels);
return 0;

}

The best pieces of advice you've gotten so far are:

Control your loop with an integer, not a floating-point variable.

Arithmetic" by David Goldberg.

--
Keith Thompson (The_Other_Keith) ks...@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"

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 1:07 am
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Wed, 24 Mar 2010 22:07:21 -0700
Local: Thurs, Mar 25 2010 1:07 am
Subject: Re: Equality failure in <=.
On Wed, 24 Mar 2010 15:26:10 -0700, "Robbie Hatley"

It is not fixed.  You have simply camouflaged it.  You have managed to
obtain the output you want with no understanding of what the real
issue still is!

What is the true value of CelsInc?  Hint - it is not numerical value
0.2 that you think it is.

--
Remove del for email

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 4:39 am
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Thu, 25 Mar 2010 01:39:50 -0700
Local: Thurs, Mar 25 2010 4:39 am
Subject: Re: Equality failure in <=.

"Barry Schwarz" wrote:
> "Robbie Hatley" wrote:

> > The <= issue is also now fixed.  I used a +0.0001 "fuzz zone".

> It is not fixed.

Oh, but it *is* fixed.

> You have simply camouflaged it.

No, I "fuzzed" it.  Read on.

> You have managed to obtain the output you want

Precisely.  By adding a "fuzz zone" of 0.00001 in a program
where the numbers are increasing in increments of at least
0.001 (100 times larger), I've "fuzzed-out" (or "overloaded",
in C++ lingo) the meaning of operator "<=" to mean
"less-than OR approximately-equal-to-give-or-take-0.00001",
which cures the problem in the most-direct and simplist way.

This "fuzz zone" approach can work well with much less code bloat
than the "convert-to-integers" method, PROVIDED that you can find
a fuzz value that is at least an 2 magnitude smaller than the
"granularity" of the numbers involved, and 4 orders of magnitude
larger than the floating-point errors involved.  In some cases,
that can't be done, and you have to use "convert-to-integers".
But In the case of my temp conversion programs, a suitable
fuzz value was very easy to find, because the granularity is
known.

these two methods?  Simple: I was wondering if anyone knew
any *OTHER* methods I hadn't considered.)

> with no understanding of what the real issue still is!

I understand the problem, and the "use integers" solution
which others here have recommended to me.  I just chose to avoid
the hassle of that approach for these simple programs.
The "integers" approach does have downsides: code bloat,
complexity, unclarity, fragility, unmaintainability.

Oh, and you *STILL* have to use a "fuzz zone", to avoid converting
to the next lower integer.  Think about it!  If you use an "expand
by 1000" technique, you want 0.1999999999 to expand to 200, not
199.  So you have to fuzz it by adding 0.01 to all your expansions
after multiplying by 1000 but before casting to int.  Else you're
right back to "Equality failure of <= operator".

(Why 0.01?  Two orders of magnitude below 1, and about four orders
of magnitude above the x1000 expanded floating-point errors.)

If I used the "convert-to-integers" method for my temp-conversion
programs, they would have to look something like the folowing
(untested) code:

========= BEGIN "CONVERT-TO-INTEGERS" METHOD ======================

double cels_min_flt = atof(argv[1]);
double cels_max_flt = atof(argv[2]);
double cels_inc_flt = atof(argv[3]);
int    cels_min_int = (int)(1000.0 * cels_min_flt + 0.01);
int    cels_max_int = (int)(1000.0 * cels_max_flt + 0.01);
int    cels_inc_int = (int)(1000.0 * cels_inc_flt + 0.01);
int    cels_val_int = 0;
double cels_val_flt = 0.0;
double fahr_val_flt = 0.0;

printf("    Cels        Fahr   \n");

for
(
cels_val_int  = cels_min_int; /* initialize    */
cels_val_int <= cels_max_int; /* crisp-compare */
cels_val_int += cels_inc_int  /* increment     */
)
{
/* We're past the "<=" hurdle, so convert back to double: */
cels_val_flt = ((double)cels_val_int)/1000.0;

/* Now continue with calculation in floating-point: */
fahr_val_flt = (((cels_val_flt*180.0)/100.0)+32);

/* And, finally, print the results: */
printf("%10.3f   %10.3f\n\n", cels_val_flt, fahr_val_flt);
}

========= END "CONVERT-TO-INTEGERS" METHOD ======================

And we have achieved... WHAT, exactly?  Massive code bloat,
monstrous unclarity of code, and huge potentials for maintainance
errors.

Now, compare with *my* approach, which uses *no* conversions,
just a single 0.00001 fuzz value:

======== BEGIN "FUZZ-ZONE" METHOD =======================

double cels_min = atof(argv[1]);
double cels_max = atof(argv[2]);
double cels_inc = atof(argv[3]);
double cels = 0.0;
double fahr = 0.0;

printf("    Cels        Fahr   \n");

for
(
cels  = cels_min          ; /* initialize    */
cels <= (cels_max+0.00001); /* fuzzy-compare */
cels += cels_inc            /* increment     */
)
{
fahr = (((cels*180.0)/100.0)+32);
printf("%10.3f   %10.3f\n", cels, fahr);
}

======== END "FUZZ-ZONE" METHOD =======================

*Much* simpler and more efficient, due to no conversions.
Much more clear and understandable.  Much easier to maintain.

The appropriate fuzz value of 0.00001 ensures that "<=" always
does what we want it to, thus achieving everything that the
"integers" method does, without all the bloat and confusion.

> What is the true value of CelsInc?  Hint - it is not numerical value
> 0.2 that you think it is.

Apparently it's not exactly 0.2, though I had thought it would be,
because it's a terminating decimal.

I'm quite aware that at the realm of about 1 part in 1E10,
there are errors in the internal representations of floating point
numbers.  There's only a finite number of bits, after all, and many
real numbers need an infinite number of bits to exactly represent them:
1/3 = 0.3333333333...(to infinity)   (can't be represented exactly)
pi  = 3.1415926535...(to infinity)   (can't be represented exactly)

But as for 0.2, I'm not sure why it can't be exactly represented.
Perhaps you can enlighten?

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 5:14 am
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Thu, 25 Mar 2010 02:14:15 -0700
Local: Thurs, Mar 25 2010 5:14 am
Subject: Re: Equality failure in <=.

"Keith Thompson" wrote:
> 0.001 should be 0.2, yes?

Yep, typo.

> In addition to the other advice you've gotten, it might be
> instructive to print the values to greater precision.

Yes, that would show, perhaps, what's happening with 0.2.

Let's try that....

/* zero-point-two.c */
#include <stdio.h>
int main(void)
{
const double zero_point_two = 0.2;
printf("zero_point_two = %.40f\n", zero_point_two);
return 0;

}

OUTPUT:
zero_point_two = 0.2000000000000000111022302462515654042360

It's showing errors starting at 1E-17.

Not sure, however, just how much of that is in the number itself,
and to what extent it's due to printf()'s limitations.  But one
thing is clear: if *ANY* of those non-zero digits to the right
of "0.2000000000000000" are actually being stored in the variable
"zero_point_two", then it will cause exactly the bug I was
having.  And clearly my fuzz value of 0.00001 is perfect:
far below granularity of 0.001, but far above error value
0.000000000000000011102230...

> The best pieces of advice you've gotten so far are:

> Control your loop with an integer, not a floating-point variable.

Considered, rejected.  Fuzz-value method is better and simpler
for this application.

> Floating-Point Arithmetic" by David Goldberg.

Thanks for the reference, I'll try to hunt that down.

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 5:47 am
Newsgroups: comp.lang.c
From: "Robbie Hatley" <see.my.signat...@for.my.contact.info>
Date: Thu, 25 Mar 2010 02:47:21 -0700
Local: Thurs, Mar 25 2010 5:47 am
Subject: Re: Equality failure in <=.

Out of curiosity, I expanded the display of 0.2 to 60 digits:

/* zero-point-two.c */
#include <stdio.h>
int main(void)
{
const double zero_point_two = 0.2;
printf("zero_point_two = %.60f\n", zero_point_two);
return 0;

}

OUTPUT:
zero_point_two = 0.200000000000000011102230246251565404236000000000000000000000

So printf() doesn't print random gibberish at any point;
it either print's what's there, or it prints 0 if nothing
is there.

Hence, the actual ammount of error in the double-precision
floating-point representation of 0.2 on my system & OS & compiler is
0.000000000000000011102230246251565404236

WHich explans why
40.0 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2
== 41.00000000000000005551115123125782702118
> 41.0

BUT,
41.000000000000000055511151231257827021180 < 41.00001
AND
41.200000000000000066613381477509392425416 > 41.00001

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant

"Robbie Hatley" <see.my.signat...@for.my.contact.info> wrote in message

news:4aGdnbwMXr2wtDbWnZ2dnUVZ_sednZ2d@giganews.com...

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 6:04 am
Newsgroups: comp.lang.c
From: Mark Dickinson <dicki...@gmail.com>
Date: Thu, 25 Mar 2010 03:04:11 -0700 (PDT)
Local: Thurs, Mar 25 2010 6:04 am
Subject: Re: Equality failure in <=.
On Mar 25, 9:47 am, "Robbie Hatley"

Actually, it looks like your system's printf gets bored at around 40
digits and just starts printing zeros instead of calculating any
further.  If it printed the exact value stored then you would have
seen:

0.200000000000000011102230246251565404236316680908203125000000

--
Mark

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 6:10 am
Newsgroups: comp.lang.c
From: Nick Keighley <nick_keighley_nos...@hotmail.com>
Date: Thu, 25 Mar 2010 03:10:58 -0700 (PDT)
Local: Thurs, Mar 25 2010 6:10 am
Subject: Re: Equality failure in <=.
On 25 Mar, 09:14, "Robbie Hatley"

<see.my.signat...@for.my.contact.info> wrote:
> "Keith Thompson" wrote:
> > The best pieces of advice you've gotten so far are:

> > Control your loop with an integer, not a floating-point variable.

> Considered, rejected.  Fuzz-value method is better and simpler
> for this application.

idiot

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 9:25 am
Newsgroups: comp.lang.c
From: Ben Bacarisse <ben.use...@bsb.me.uk>
Date: Thu, 25 Mar 2010 13:25:04 +0000
Local: Thurs, Mar 25 2010 9:25 am
Subject: Re: Equality failure in <=.

It's more complex than that.  If you have a suitable version of printf
(i.e. one that support C99 formats) you can see what is actually
"there" by using the %a format.  It takes a while to work out what
the output means (it is a floating point number in hexadecimal) but it
does show you what is really stored in a double.

<snip>
--
Ben.

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 10:06 am
Newsgroups: comp.lang.c
From: Pillsy <pillsb...@gmail.com>
Date: Thu, 25 Mar 2010 07:06:48 -0700 (PDT)
Local: Thurs, Mar 25 2010 10:06 am
Subject: Re: Equality failure in <=.
On Mar 25, 4:39 am, "Robbie Hatley"
<see.my.signat...@for.my.contact.info> wrote:

[...]

> But as for 0.2, I'm not sure why it can't be exactly represented.
> Perhaps you can enlighten?

Because binary floating point numbers can only exactly represent
fractions where the denominator is a power of 1/2. In particular, this
means that 0.2 = 1/5 cannot be exactly represented, in much the same
way that 1/3 cannot be represented as a decimal floating point number.

HTH,
Pillsy

To post a message you must first join this group.
You do not have the permission required to post.
More options Mar 25 2010, 11:35 pm
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Thu, 25 Mar 2010 20:35:21 -0700
Local: Thurs, Mar 25 2010 11:35 pm
Subject: Re: Equality failure in <=.
On Thu, 25 Mar 2010 01:39:50 -0700, "Robbie Hatley"

Only by the unfortunate accident that all the values in question had
sufficiently few significant digits.  Since a double is guaranteed to
have at least 10 significant digits, 40. + 0.00001 will always be
greater than 40.  But on a system where float has only 6 significant
digits, 40.f + 0.00001f will be equal to 40.f.  In this situation,
your "fuzz zone" will do nothing.

Not if you believe what you wrote above.  My system has built in
decimal floating point and I don't need the fuzz at all if the
fraction does not exceed the number of significant digits a double can
hold.

snip

>But as for 0.2, I'm not sure why it can't be exactly represented.
>Perhaps you can enlighten?

One procedure for converting a decimal fraction to binary is to
multiply by two, use the integer portion, and repeat with the
fractional portion, stopping when the fraction is 0

For example, 0.375 * 2 = 0.75; keep the 0.  0.75 * 2 = 1.5; keep the
1.  0.5 * 2 = 1.0; keep the 1 and stop.  The binary representation of
0.375 is 0.011.

Now try it with 0.2 and let me know when the process terminates.

--
Remove del for email