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

Equality failure in <=.

85 views
Skip to first unread message

Robbie Hatley

unread,
Mar 24, 2010, 4:03:39 PM3/24/10
to

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


Nick

unread,
Mar 24, 2010, 4:18:40 PM3/24/10
to
"Robbie Hatley" <see.my.s...@for.my.contact.info> writes:

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

Eric Sosman

unread,
Mar 24, 2010, 4:59:15 PM3/24/10
to
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
eso...@ieee-dot-org.invalid

Robbie Hatley

unread,
Mar 24, 2010, 5:08:04 PM3/24/10
to

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

Seebs

unread,
Mar 24, 2010, 6:12:12 PM3/24/10
to
On 2010-03-24, Robbie Hatley <see.my.s...@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...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Robbie Hatley

unread,
Mar 24, 2010, 6:26:10 PM3/24/10
to

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

Phil Carmody

unread,
Mar 24, 2010, 8:04:52 PM3/24/10
to
"Robbie Hatley" <see.my.s...@for.my.contact.info> writes:
> 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).
...

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

> 40.800 105.440
>
> Where is 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.

Don't guess; read:
/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

Eric Sosman

unread,
Mar 24, 2010, 8:41:47 PM3/24/10
to
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.
(Given your remarks about having seen bad things "in production
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
code" I urge you to cast your ignorance aside ASAP. Please.)

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

Keith Thompson

unread,
Mar 25, 2010, 12:19:33 AM3/25/10
to
"Robbie Hatley" <see.my.s...@for.my.contact.info> writes:
> 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):

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
thread, I can't find the article containing your actual code without
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.

Read "What Every Computer Scientist Should Know About Floating-Point
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"

Barry Schwarz

unread,
Mar 25, 2010, 1:07:21 AM3/25/10
to

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

Robbie Hatley

unread,
Mar 25, 2010, 4:39:50 AM3/25/10
to

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

(So why was I even asking about this here, if I already know
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?

Robbie Hatley

unread,
Mar 25, 2010, 5:14:15 AM3/25/10
to

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

> Read "What Every Computer Scientist Should Know About
> Floating-Point Arithmetic" by David Goldberg.

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

Robbie Hatley

unread,
Mar 25, 2010, 5:47:21 AM3/25/10
to

ADDENDUM:

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.s...@for.my.contact.info> wrote in message
news:4aGdnbwMXr2wtDbW...@giganews.com...

Mark Dickinson

unread,
Mar 25, 2010, 6:04:11 AM3/25/10
to
On Mar 25, 9:47 am, "Robbie Hatley"

<see.my.signat...@for.my.contact.info> wrote:
> ADDENDUM:
>
> 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.

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

Nick Keighley

unread,
Mar 25, 2010, 6:10:58 AM3/25/10
to
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

Ben Bacarisse

unread,
Mar 25, 2010, 9:25:04 AM3/25/10
to
"Robbie Hatley" <see.my.s...@for.my.contact.info> writes:

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

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.

Pillsy

unread,
Mar 25, 2010, 10:06:48 AM3/25/10
to
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

Barry Schwarz

unread,
Mar 25, 2010, 11:35:21 PM3/25/10
to
On Thu, 25 Mar 2010 01:39:50 -0700, "Robbie Hatley"
<see.my.s...@for.my.contact.info> wrote:

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

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.

>
>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.
>
>(So why was I even asking about this here, if I already know
>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

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.

0 new messages