This problem will always exist with floating point arithmetic, you can delay it with more digits of precision, but when used incorrectly it will bite you.

Exact integer and rational arithmetic do not have this problem but it is not always possible to use them.

]]>bobbym wrote:

Notice how instead of getting 0 he gets 0.20539126e-14, but at least the for next loop terminates.

Yes - I'll have to remember that for situations where that is important (or maybe I should make it a habit anyway).

Some day this quirk won't exist and we won't have to dream up workarounds...and we'll laugh at the clunky ways of the old days.

]]>I tried that, but I got the same incorrect responses as before. Maybe I didn't code it correctly. I'll try again...

```
for n=10 to 0 step -1/5
print n
next n
```

Notice how instead of getting 0 he gets 0.20539126e-14, but at least the for next loop terminates.

]]>Its ctrl + pause/break : this key is above the arrow keys (at the top).

Ah - found it! I'd never used that key before and must have skimmed over it when looking for it.

It stops program execution, as you said.

Thanks!

]]>I'll have to ask LB, because the only way I can manually quit a program is via the Task Manager (CTRL + ALT + DELETE). And that's annoying.

]]>ctrl + break is supposed to stop a program.

]]>bobbym wrote:

Try this in LBasic: Don't use the input command to enter f. Just change it manually. We expect to count down from 10 by 1/3 until we get to 0. Watch what happens and then try 1/2,1/6,1/8,1/10,1/5 for f.

I tried those exercises and I see what you mean. 1/10 surprised me.

I changed your code to run to 200 to avoid the endless looping. Btw, I don't know how to stop the program mid-stream - do you?

For terminated results LBASIC prints just the integer "200", but for non-terminations it prints "200.0". I suppose LB is saying that the number is not an integer, and that the number of zeros preceding other decimal digits exceeds its precision limit.

If I use a for next loop we get the correct response.

I tried that, but I got the same incorrect responses as before. Maybe I didn't code it correctly. I'll try again...

Re your first workaround:

As you suggested, I changed the offending line. I came up with:

Same results as before, in the same time.

]]>I don't have a mathematical solution to this problem or to mine at:

http://www.mathisfunforum.com/viewtopic … 51#p116951

phrontister wrote:

If you have time, could you post the code for solving this in BASIC? That's the only language I 'know' atm - I'm hoping to venture into something else some day when I get some spare(!) time...maybe Python.

Since you got me looking at Basic, I dug up an old, old copy of QBasic 7.1. It only has an old dos gui. but it's like 25 times faster than LBasic 4.02 on my machines.

]]>Thanks for all of that! I could only look at it quickly this a.m. and I've got to run now, so I'll have a closer look at it tonight.

bobbym wrote:

Workaround #2:

The principle of this workaround came to me in bed last night just before I went to sleep (my mind's most productive moments!), and I was going to post about it morning...but you've saved me the trouble.:)

]]>Forgive the ugliness and spaghetti code look of my prog. It is just to illustrate a point. Also I have not used any Basic for more than 20 years.

Try this in LBasic: Don't use the input command to enter f. Just change it manually. We expect to count down from 10 by 1/3 until we get to 0. Watch what happens and then try 1/2,1/6,1/8,1/10,1/5 for f. Important: this is not a bug in LBasic it is inherent in the way computers do arithmetic.

```
a=10
f=1/3
[loop]
a=a-f
if a=0 then print "done" : end
print a
goto [loop]
Or try this
x = 0
f=1/7
while x <> 500
x = x + f
print x
wend
end
```

For some fractions they terminate as expected and for some others they don't. Floating point arithmetic is not the same as how humans work with numbers. Where we see the number line as continuous, to the computer there are gaps like morse code. Some numbers cannot be represented in binary in a finite amount of digits.

For humans (a-b)^2 = (a^2 - 2 a b +b^2) is an identity. For computers it is not.

If I use a for next loop we get the correct response. Why? Because the for next loop is smart enough not to test floating point numbers for equality as she has done. It tests greater than or less than which is much more accurate.

These were prepared quickly and may contain bugs but the principles are standard from numerical analysis.

]]>Go here to see a little bit what I mean. The first part with excel is meaningful.

http://www.wolfram.com/broadcast/screen … ghtanswer/

Yes - I think I can see that relying on results from fractions can, in some circumstances, produce errors.

Here's a fix I thought up that restricts the number of fractions in that line to one, and it occurs after all the other calculations are done:-

If (n(1) * (n(5) * 10 + n(6)) * (n(8) * 10 + n(9)) + n(4) * (n(2) * 10 + n(3)) * (n(8) * 10 + n(9)) + n(7) * (n(2) * 10 + n(3)) * (n(5) * 10 + n(6))) / ((n(2) * 10 + n(3)) * (n(5) * 10 + n(6)) * (n(8) * 10 + n(9))) = 1 Then

nValids = nValids + 1

Is this the sort of thing you mean, Bobby? It seems a bit wordy...you've probably got a better way of expressing that.

The code runs fine, but a bit longer.

What's the other fix you've got in mind? (or the other two, if mine isn't one).

]]>Even though you see code like this all the time, in every language, her test is numerically unsound and there are 2 fixes for it. It worked here but you could almost say she got lucky with it.

Go here to see a little bit what I mean. The first part with excel is meaningful.

http://www.wolfram.com/broadcast/screen … ghtanswer/

bobbym wrote:

If (n(1) / (n(2) * 10 + n(3))) + (n(4) / (n(5) * 10 + n(6))) + (n(7) / (n(8) * 10 + n(9))) = 1 Then

nValids = nValids + 1My beef with her code is this line!

What beef is that? Do you have a fix for it, or a better approach altogether?

]]>