Go Back  Xtreme Visual Basic Talk > Legacy Visual Basic (VB 4/5/6) > General > VB Bug - Rounding Doubles or something?


Reply
 
Thread Tools Display Modes
  #1  
Old 03-05-2006, 10:04 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default 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?
Reply With Quote
  #2  
Old 03-05-2006, 11:44 PM
mkaras's Avatar
mkaras mkaras is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
Default

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.
Reply With Quote
  #3  
Old 03-06-2006, 01:31 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default

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.
Reply With Quote
  #4  
Old 03-06-2006, 01:52 PM
Flyguy's Avatar
Flyguy Flyguy is offline
Lost Soul

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Vorlon
Posts: 18,882
Default

Have a look at this recent thread
http://www.xtremevbtalk.com/showthread.php?t=255512
Reply With Quote
  #5  
Old 03-06-2006, 02:07 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default

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!
Reply With Quote
  #6  
Old 03-06-2006, 03:38 PM
Iceplug's Avatar
Iceplug Iceplug is offline
MetaCenturion

Retired Moderator
* Guru *
 
Join Date: Aug 2001
Location: California, USA
Posts: 16,583
Default

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

Iceplug, USN
Quadrill 1 Quadrill 2 (full) Quadrill 3 JumpCross .NET Website is ALIVE! - DL Platform Tour for VB.NET! Posting Guidelines Hint: Specify your location in your user cp profile if you want compassion!
Reply With Quote
  #7  
Old 03-06-2006, 05:21 PM
Cerian Knight's Avatar
Cerian Knight Cerian Knight is offline
Multi-Technologist

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 3,734
Default

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'.
Reply With Quote
  #8  
Old 03-06-2006, 07:31 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default

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.
Reply With Quote
  #9  
Old 03-06-2006, 08:10 PM
Cerian Knight's Avatar
Cerian Knight Cerian Knight is offline
Multi-Technologist

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 3,734
Default

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
Reply With Quote
  #10  
Old 03-06-2006, 08:23 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default

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
Reply With Quote
  #11  
Old 03-06-2006, 08:35 PM
Cerian Knight's Avatar
Cerian Knight Cerian Knight is offline
Multi-Technologist

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 3,734
Default

Your welcome. Thought you might enjoy this thread complete with many versions of project code:
http://www.xtremevbtalk.com/showthread.php?t=226471
Reply With Quote
  #12  
Old 03-06-2006, 10:36 PM
Perfect_Man Perfect_Man is offline
Contributor
 
Join Date: Apr 2003
Location: canada
Posts: 535
Default

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
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->