*** NOT A NEWBIE *** - Is there a bug in CFLOOP with decimal STEP?

OK - we were working on a complex app when we ran across a glitch.  We finally stripped out all of the interesting code, leaving ourselves with just the loop, and I can't believe what I'm seeing.  Can anyone comment on this ---

<CFLOOP from="1.3" to="0.7" step="-0.1" index="x">
      <CFOUTPUT><strong>x=#x# ... int(x*100)/100=#evaluate(int(x*100)/100)#</strong> ... </CFOUTPUT>
      <CFIF x GT 1>x gt 1 ...</cfif>
      <CFIF int(x*100)/100 EQ 1>x eq 1 ...</cfif>
      <CFIF x LT 1>x lt 1 ...</cfif>
      <BR>
</CFLOOP>

What this SHOULD run as is:

x=1.3 ... int(x*100)/100=1.3 ... x gt 1 ...
x=1.2 ... int(x*100)/100=1.2 ... x gt 1 ...
x=1.1 ... int(x*100)/100=1.09 ... x gt 1 ...
x=1 ... int(x*100)/100=1 ... x eq 1 ...
x=0.9 ... int(x*100)/100=0.9 ... x lt 1 ...
x=0.8 ... int(x*100)/100=0.8 ... x lt 1 ...
x=0.7 ... int(x*100)/100=0.7 ... x lt 1 ...

But what we are seeing is:

x=1.3 ... int(x*100)/100=1.3 ... x gt 1 ...
x=1.2 ... int(x*100)/100=1.2 ... x gt 1 ...
x=1.1 ... int(x*100)/100=1.09 ... x gt 1 ...   <<<<<< Look Here
x=1 ... int(x*100)/100=0.99 ... x lt 1 ...    <<<<<< Look Here
x=0.9 ... int(x*100)/100=0.89 ... x lt 1 ...    <<<<<< Look Here
x=0.8 ... int(x*100)/100=0.8 ... x lt 1 ...
x=0.7 ... int(x*100)/100=0.7 ... x lt 1 ...

When I change the script to:

<CFLOOP from="1.3" to="0.7" step="-0.1" index="x">
      <CFOUTPUT><strong>x=#x# ... int(x*100000)/100000=#evaluate(int(x*100000)/100000)#</strong> ... </CFOUTPUT>
      <CFIF x GT 1>x gt 1 ...</cfif>
      <CFIF int(x*100)/100 EQ 1>x eq 1 ...</cfif>
      <CFIF x LT 1>x lt 1 ...</cfif>
      <BR>
</CFLOOP>

I get ...

x=1.3 ... int(x*100000)/100000=1.3 ... x gt 1 ...
x=1.2 ... int(x*100000)/100000=1.2 ... x gt 1 ...
x=1.1 ... int(x*100000)/100000=1.09999 ... x gt 1 ...
x=1 ... int(x*100000)/100000=0.99999 ... x lt 1 ...
x=0.9 ... int(x*100000)/100000=0.89999 ... x lt 1 ...
x=0.8 ... int(x*100000)/100000=0.8 ... x lt 1 ...
x=0.7 ... int(x*100000)/100000=0.7 ... x lt 1 ...

Could it be some sort of floating point glitch in CF (or Java) when stepping backwards?  I'm totally at a loss - really.
Can anyone recreate this problem?  Any ideas on what would cause it?

I'm on MX 7 Standard ... Version: 7,0,1,116466  
Windows 2000 Server
Dell with Dual Xeons
Update Level /C:/CFusionMX7/lib/updates/chf7010001.jar  
Java version 1.4.2_08

FYI, when I run the test "forwards", ie:
<CFLOOP from="0.7" to="1.3" step="0.1" index="x">
      <CFOUTPUT><strong>x=#x# ... int(x*100000)/100000=#evaluate(int(x*100000)/100000)#</strong> ... </CFOUTPUT>
      <CFIF x GT 1>x gt 1 ...</cfif>
      <CFIF int(x*100)/100 EQ 1>x eq 1 ...</cfif>
      <CFIF x LT 1>x lt 1 ...</cfif>
      <BR>
</CFLOOP>

I get the same crazy results:
x=0.7 ... int(x*100000)/100000=0.7 ... x lt 1 ...
x=0.8 ... int(x*100000)/100000=0.8 ... x lt 1 ...
x=0.9 ... int(x*100000)/100000=0.89999 ... x lt 1 ...
x=1 ... int(x*100000)/100000=0.99999 ... x lt 1 ...
x=1.1 ... int(x*100000)/100000=1.09999 ... x gt 1 ...
x=1.2 ... int(x*100000)/100000=1.2 ... x gt 1 ...
x=1.3 ... int(x*100000)/100000=1.3 ... x gt 1 ...

At least now I know I'm not crazy (could not figure out why 1 would not equal 1 until we built the above test).

HELP !!!! : )

Thanks
LVL 1
drgdrgAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RCorfmanCommented:
Floating Point numbers are never exact... unfortunately. When you convert from decimal to binary internally, turns out that .1 (decimal), when converted to binary is a 'repeating fraction' (I forget the term). Basically, it turns out to be (IN Binary .110011001100110011001100 (forever). This causes rounding, sort of like 1/3 does in decimal.

I suspect if you use whole numbers and then just divide the answer by 10, your problem will go away.
I'm a little surprised it manifests itself so fast, but That is the nature of floating point.
RCorfmanCommented:
So, I tried just manually subtracting one from X using cfset and it didn't manifest the problem.
<CFLOOP> index must not be carrying floating point to many digits. I agree that there is something strange, and it is with cfloop.

Now, for something even more fun. You can ALMOST solve this by getting rid of the fraction and multiplying it by to all around... but notice that it isn't EQ one..., nor greater and less than ;)

<CFLOOP from="13" to="07" step="-01" index="x">
     <CFOUTPUT><strong>x=#x/10# ... int(x*100)/100=#evaluate(int(x*100)/1000)#</strong> ... </CFOUTPUT>
     <CFIF x/10 GT 1>x gt 1 ...</cfif>
     <CFIF int(x*100)/10 EQ 1>x eq 1 ...</cfif>
     <CFIF x/10 LT 1>x lt 1 ...</cfif>
     <BR>
</CFLOOP>

x=1.3 ... int(x*100)/100=1.3 ... x gt 1 ...
x=1.2 ... int(x*100)/100=1.2 ... x gt 1 ...
x=1.1 ... int(x*100)/100=1.1 ... x gt 1 ...
x=1 ... int(x*100)/100=1 ...                             <<<< what's this one? Not <, =, or >
x=0.9 ... int(x*100)/100=0.9 ... x lt 1 ...
x=0.8 ... int(x*100)/100=0.8 ... x lt 1 ...
x=0.7 ... int(x*100)/100=0.7 ... x lt 1 ...
RCorfmanCommented:
I did confirm that it ISN'T CFLOOP. It has to do with floating point math...

<CFSET x=1.3>
<CFLOOP from="1.3" to="0.7" step="-0.1" index="y">
     <CFOUTPUT><strong>x=#x# ... int(x*100)/100=#evaluate(int(x*100)/100)#</strong> ... </CFOUTPUT>
     <CFIF x GT 1>x gt 1 ...</cfif>
     <CFIF int(x*100)/100 EQ 1>x eq 1 ...</cfif>
     <CFIF x LT 1>x lt 1 ...</cfif>
     <BR>
     <CFSET X=X-.1>
</CFLOOP>

Same odd result. X is no longer part of the cfloop.
x=1.3 ... int(x*100)/100=1.3 ... x gt 1 ...
x=1.2 ... int(x*100)/100=1.2 ... x gt 1 ...
x=1.1 ... int(x*100)/100=1.09 ... x gt 1 ...
x=1 ... int(x*100)/100=0.99 ... x lt 1 ...
x=0.9 ... int(x*100)/100=0.89 ... x lt 1 ...
x=0.8 ... int(x*100)/100=0.8 ... x lt 1 ...
x=0.7 ... int(x*100)/100=0.7 ... x lt 1 ...
drgdrgAuthor Commented:
Absolutely crazy.  The way I got around it was to loop

<CFLOOP from="20" to="1" index="y" step="-1">
  <CFSET x = y / 10>
  ....

And that did the trick.  But heck... floating point errors when dealing with whole numbers?
When I was doing the step, it was

<CFLOOP from="2" to="0.1" index="x" step="-0.1">

When I got to the whole number "1" and you would diplay it, it was really .99999999999999998 (roughly)
No multiplying, no division, nothing that should cause this.

Truly odd...
RCorfmanCommented:
But, they AREN'T whole numbers. You are dealing with .1  In binary, this is just line 1/3 in decimal.  I agree it is a pain, and seems to manifest itself 'earlier' than I would have thought, but this is why they say floating point math on computers have rounding errors.  When even .1 doesn't divide out evenly to be stored, you have a problem.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Servers

From novice to tech pro — start learning today.