29 views

Skip to first unread message

Sep 26, 2019, 4:33:13 PM9/26/19

to Glowscript Users

Please excuse the newbie question.

I'm a high school teacher that is introducing vpython in an introductory high school physics class.

I'm also learning quite a bit along the way. I *think* this is a floating point problem.

When I run the following...

GlowScript 2.9 VPython

dt=0.01

t=0

x=0

v=2

while t<10:

x=x+v*dt

t=t+dt

print("time = ",t)

print("position = ",x)

I get...

time = 10.01

position = 20.02

I've played around with various values for dt. I get exactly time=10 and position=20 when dt=0.025 for example but not for 0.02.

One solution that I've come up with is:

GlowScript 2.9 VPython

dt=0.01

t=0

x=0

v=2

while abs(t-10)>dt/2:

x=x+v*dt

t=t+dt

print("time = ",t)

print("position = ",x)

This results in time=10 and position=20 for every dt that I've tested.

My questions:

1. Is there a simpler solution here?

2. Do you have suggestions on how I can simply explain this to my beginning coders?

Thanks in advance.

Sep 26, 2019, 9:47:42 PM9/26/19

to Glowscript Users

This is a fundamental issue with computers, which cannot represent floating point values exactly. Typically a floating-point number is represented in memory by eight 8-bit bytes (64 bits), with one bit representing the sign, 11 bits representing the exponent, and 52 bits representing the mantissa. 2**52 is an integer with about 16 decimal places, and the 11 bits of exponent can express -10**1024 to 10**1024.

When these necessarily not quite precise representations of floating point numbers are added the result can be slightly different from what you expect. One way to deal with this is to do something like this:

dt = 0.01

t = 0

while t < 10-dt/2:

t = t+dt

print(t) # prints 10

Another scheme is something like the following, using integers for the loop quantity n, which don't have the imprecision of floating point numbers (assuming that n doesn't get bigger than 2**64):

dt = 0.01

t = 0

n = 0

while n < 10*100:

t = t+dt

n = n+1

print(t) # prints 10

Bruce

Sep 26, 2019, 9:51:45 PM9/26/19

to glowscri...@googlegroups.com

Also, fractions with denominators that are powers of two, such as 1/2,1/4,3/8 and 5/16 are represented exactly in binary, without rounding. Use .25 or .0125

Harlan

--

---

You received this message because you are subscribed to the Google Groups "Glowscript Users" group.

To unsubscribe from this group and stop receiving emails from it, send an email to glowscript-use...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/glowscript-users/CA%2BWuaScZAR9t_DsRmQA8Wvoiz%3DrmWDT9GX2pFnr2aa4STCQCGg%40mail.gmail.com.

Sep 27, 2019, 12:53:18 PM9/27/19

to Glowscript Users

Thanks for the responses.

I will spend a bit of time with my students exploring this issue. I like the while t < 10-dt/2: solution.

Harlan:

Your answer makes sense to me but I found the real world results a bit mixed.

dt=0.025 works

dt=0.0125 doesn't work.

I also posted this problem on Twitter and I like the idea of adding a line:

print(t,t<10)

inside the loop.

By following the last lines of the output (this example using dt=0.0125)

9.9875 True

10 True

10.0125 False

students should see the "not quite precise representations of floating point numbers".

Thanks again for your quick and informative responses!

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu