 |

03-05-2006, 10:04 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
VB Bug - Rounding Doubles or something?
|
The weirdest thing happens in my Application. It is extremely sensitive to calculations, and well, things go absolutely crazy! I have particles with exact same mass. I am calculating gravity F = mg. THen in another loop, i loop them all again and do a = F/m to get acceleration. I run the application, and the particles fall to the ground.
BUT!!!! If i start 2 particles at y = 500 and let em fall to y = 0, The Difference between their y values is like 1.7E-15, then it goes to -1.7E-15, then 0.2E-16, and just like that... This part i absolutely dont understand. They differ by that amount, and yet i increment them in the EXACT same way...
Anyone has any ideas what the hell is happening?
|
|

03-05-2006, 11:44 PM
|
 |
Ultimate Contributor
Retired Leader * Expert *
|
|
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
|
|
|
It is a devil of a problem!!
Are you using a bad mix of variable types in your application? It may be wise to look carefully and make sure all variable are of the type Double. Also make sure to use Option Explicit at the top of your form or module code page to ensure that you force full control of variable types to be in your hands as opposed to letting VB assume the types.
|
|

03-06-2006, 01:31 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
|
mkaras thanks for your response. I have done furtherer investigations and this is what i came up with.
1. I had the option explicit there
2. I also made sure all variables are doubles except for i, j that are used for loops
I made it print out EVERYThing, and i found out that VB Cant do the Square Root function.
d = Sqr((n(.front).X - n(.end).X) ^ 2 + (n(.front).Y - n(.end).Y) ^ 2)
This is the formula. Then i have another variable called Space, which is set to 40 by default, it is also double. So i run this. DeltaX is 0, DeltaY is 1600. Square root is 40. Now what i do next is
X = d - Space
d = 40
Space = 40
X = -7.105427357601E-15
THIS is the problem. I have No idea how VB calculated this, but this is the weirdest thing ever. And they are all Doubles.
edit
WoW, this is actually really a VB Bug! Just try to type into google
7.105427357601
Its a special number! There is some problem with floating point comparisons or something
|
Last edited by Perfect_Man; 03-06-2006 at 01:39 PM.
|

03-06-2006, 01:52 PM
|
 |
Lost Soul
Super Moderator * Guru *
|
|
Join Date: May 2001
Location: Vorlon
Posts: 18,882
|
|
|

03-06-2006, 02:07 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
|
Thanks FlyGuy, it seems to be the exact same problem. I converted all my Doubles to Single's, and my Application blows up ever faster than before, i think it just cant be fixed the application is too sensitive to small scale changes, because of all the quadratic formulas and the number of iterations... I think ill just give up on it. I also tried to do something like
if x < 1E-14 then x = 0
but it just took a little longer, and it blew up anyway...
Thanks though!
|
|

03-06-2006, 03:38 PM
|
 |
MetaCenturion
Retired Moderator * Guru *
|
|
Join Date: Aug 2001
Location: California, USA
Posts: 16,583
|
|
|
It's not a VB Bug, it's a double precision bug... how does a value cause your program to blow up? Typically, you only employ operations that handle ranges of double values...
|
|

03-06-2006, 05:21 PM
|
 |
Multi-Technologist
Super Moderator * Expert *
|
|
Join Date: May 2004
Location: Michigan
Posts: 3,734
|
|
Quote:
|
Originally Posted by Perfect_Man
Thanks FlyGuy, it seems to be the exact same problem. I converted all my Doubles to Single's, and my Application blows up ever faster than before, i think it just cant be fixed the application is too sensitive to small scale changes, because of all the quadratic formulas and the number of iterations... I think ill just give up on it. I also tried to do something like
if x < 1E-14 then x = 0
but it just took a little longer, and it blew up anyway...
Thanks though!
|
Not sure if you read through that thread far enough. The implication was that singles might appear to 'fix' the problem, but for particle simulations I wouldn't try that. The formula you propose was basically correct for working with doubles, but I'm not certain if you should actually be using 'abs(x) < 1E-14 then x=0'. In any case, a fair amount of imprecision is coming from using ^2, which should be replaced by calculating the bases into a temps and then using temp*temp. If the Sqr result is used for comparisons only then don't do it: 'If Sqr(x) = 5' is the same as saying 'If ABS(x) = 25'.
|
|

03-06-2006, 07:31 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
Ok i will post the code because it is really short, and i can see im causing confusion here... n is a Node, with its x,y positions, vx, vy velocity, fx and fy force pools, and mass m. t is a 'Thread'. Threads LINK the nodes, and they have integers front and end, that point to the nodes that the thread is connecting.
Code that matters:
Code:
Private Sub Timer1_Timer()
For i = 1 To nodes
'reset forces
n(i).Fy = 0
n(i).Fx = 0
Next i
'take care of gravity
For i = 1 To nodes
n(i).Fy = n(i).Fy + n(i).m * g
Next i
'take care of the oscilations
For i = 0 To UBound(t)
With t(i)
d = Sqr((n(.front).x - n(.end).x) ^ 2 + (n(.front).y - n(.end).y) ^ 2)
x = d - .space 'displacement from equilibrium position
'bunch of calculations that handle forces due to springs. Im quite confident
that these work. However, if x is not 0 when it should be, the program will
calculate forces that shouldnt be there, and then i get acceleration that
shouldnt be there, and the program blows up. And the 1.7 E-15 builds up
really fast....
F = .k * x
n(.front).Fx = n(.front).Fx + F * (n(.end).x - n(.front).x) * d
n(.front).Fy = n(.front).Fy + F * (n(.end).y - n(.front).y) * d
n(.end).Fx = n(.end).Fx - F * (n(.end).x - n(.front).x) * d
n(.end).Fy = n(.end).Fy - F * (n(.end).y - n(.front).y) * d
End With
Next i
'calculate acceleration
For i = 1 To nodes
With n(i)
aX = .Fx / .m
aY = .Fy / .m
.vX = .vX + aX
.vY = .vY + aY
End With
Next i
'move particles
For i = 1 To nodes
With n(i)
.x = .x + .vX
.y = .y + .vY
End With
Next i
What happens when this runs, and spring constant is bigger, like 0.3, or 1, or something, is that in only about 2 runs of this code, the x instead of being 0 (because all nodes are equally affected by gravity) is 1.7E-15, and then i get force buildup -> acceleration buildup -> more velocity -> Blow up...
Now, the way you told me to fix it i am not sure if i understood. I tried to do
d = (n(.front).x - n(.end).x) ^ 2 + (n(.front).y - n(.end).y) ^ 2
which is just omitting the Sqr (), and then
x = d - .space*.space
However this didnt work...
|
Last edited by Perfect_Man; 03-06-2006 at 07:37 PM.
|

03-06-2006, 08:10 PM
|
 |
Multi-Technologist
Super Moderator * Expert *
|
|
Join Date: May 2004
Location: Michigan
Posts: 3,734
|
|
I see you are using 'd' for more than just comparison. I hope there is no DoEvents in your Timer event, because you are not disabling the timer on entry.
Anyway, just add some local double declarations for the temps I am using. See if this helps, and read the comments:
Code:
'
dblnx = n(.front).x - n(.end).x 'is this backward?
dblny = n(.front).y - n(.end).y ' " "
d = dblnx * dblnx + dblny * dblny 'minimizes errors due to Sqr and ^
x = d - .space * .space 'rewrite so that .space is already stored as .space^2 to speed things up and remove a small error.
F = .k * x
d = Sqr(d) 'defer the Sqr until absolutely needed
n(.front).Fx = n(.front).Fx + F * (n(.end).x - n(.front).x) * d
n(.front).Fy = n(.front).Fy + F * (n(.end).y - n(.front).y) * d
n(.end).Fx = n(.end).Fx - F * (n(.end).x - n(.front).x) * d
n(.end).Fy = n(.end).Fy - F * (n(.end).y - n(.front).y) * d
|
|

03-06-2006, 08:23 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
Hey thanks so much for that! It fixed it! It doesnt blow up in midair anymore thanks a lot!!! Now it blows up when it hits the walls  , but it is i think because of the way i handle that collision, it is wrong, ill fix that hopefully soon ill get right to it
Thanks again weeee
|
|

03-06-2006, 08:35 PM
|
 |
Multi-Technologist
Super Moderator * Expert *
|
|
Join Date: May 2004
Location: Michigan
Posts: 3,734
|
|
|

03-06-2006, 10:36 PM
|
|
Contributor
|
|
Join Date: Apr 2003
Location: canada
Posts: 535
|
|
Hey thats a really cool program that guy wrote i really enjoyed it, tested it out etc  Very impressive performance for such a large number of particles...
Btw to my code, i fixed everything there was to fix, it still blows up but only in extreme cases and i know why.
See when you have .x = .x + .vx
If .vx is big enough that it Overshoots, then it all explodes. And i cant even correct for i think... But your code up there completely solved all mystifying rounding errors im so happy thats over  I was debugging that code 3 hours until i admitted that maybe its not my fault as a programmer hehe...
Any more cool simulation programs? I really enjoy all that 
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|