Loop goes into infinity

The task is to find the withdrawal amount necessary that when taken from the bank balance and when fees are applied the total fees + the withdrawal amount should equal to the bank balance so that there's nothing left. That withdrawal amount should then be displayed.

The thing is I've tried structuring the loop several ways but it still results in an infinite loop without producing the correct results.


Public conversionCost As Double = 0.035
Public atmFee As Double = 3.15

     'Calculates the maximum amount you can withdraw from current balance
    Public Sub FullDraw(ByVal flFee As Double, actBal As Double, excRate As Double)

        Dim withdrawalAmt As Double

        'redact atmfee first from current balance
        withdrawalAmt = actBal - atmFee

        'Loop until figures match to find the perfect withdrawal amount that doesn't
        'leave money behind

        Dim finalAmt As Double

        Do Until finalAmt = actBal

            withdrawalAmt -= 1

            'calculate possible conversion fee so it can be included
            Dim conversionFee As Double = conversionCost * withdrawalAmt

            'add fee

            finalAmt = withdrawalAmt + conversionFee


           Label3.Text = withdrawalAmt

    End Sub
Nicholas StephensonAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

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.

Fabrice LambertFabrice LambertCommented:
It might be because due to double imprecision, finalAmt  never becomes strictly equal to actBal.

So, use a greater than or a lower than comparision instead of an equal than.
finalAmt  never becomes strictly equal to actBal.

if you want to compare two double whether they are equal you may do like  

if ABS(finalAmt - actBal)  < 0.001

Open in new window

Do Until finalAmt = actBal

the above would not help from preventing an endless loop since you do some calculations without any checks which in my opinion never would/could match:

withdrawalAmt = actBal - atmFee
here you take actBal from arguments and atmFee from unknown
withdrawalAmt is a difference which obviously is assumed to be positive or at least >= 1
if the assumption is wrong the loop would subtract 1 from withdrawalAmt and the loop is endless because finalAmt has different sign to actBal for any case.

Dim finalAmt As Double
Do Until finalAmt = actBal
    withdrawalAmt -= 1
finalAmt is not initialized; hence the loop condition never is true initially and you subtract 1 from withdrawalAmt
it looks as if you would assume that withdrawalAmt, actBal and finalAmt are integer.

Dim conversionFee As Double = conversionCost * withdrawalAmt

conversionCost is another unknown variable and for any reason you multiply with a difference (which will be decreased by 1).
so it looks as if conversionCost is a percentage number.

if we take actBal = 100 and atmFee = 20 and conversionCost = 0.1  (what is 10%)

==>  withdrawalAmt = 80

1. loop cycle:  withdrawalAmt = 79, conversionFee = 7.9, finalAmt = 79+7.9 = 86.9
2. loop cycle:  withdrawalAmt = 78, conversionFee = 7.8, finalAmt = 78+7.8 = 85.8

you see that finalAmt would decrease with each cycle and there is no chance that it ever matches to actBal (100).

if you were using a conversionCost percentage > 25 - say 30 - you would get

1. loop cycle:  withdrawalAmt = 79, conversionFee = 23.7, finalAmt = 79+23.7 = 102.7
2. loop cycle:  withdrawalAmt = 78, conversionFee = 23.4, finalAmt = 78+23.4 = 101.4
3. loop cycle:  withdrawalAmt = 77, conversionFee = 23.1, finalAmt = 77+23.1 = 100.1
4. loop cycle:  withdrawalAmt = 76, conversionFee = 22.8, finalAmt = 76+22.8 = 98.8

you see, even if you choose  input variables which give a final amount that is greater than the balance amount, there is no real chance that amtBal ever matches finalAmt. so your code has two fatal mistakes. first, you have to correct the until condition which need to break from the loop if finalAmt is less than actBal. second, you need to find an algorithm which computes values for finalAmt that would approximate to actBal or - better - wouldn't use a loop for to computing the withdrawal amount. i don't see any reason why you need to decrease the withdrawal amount in a loop. this hardly will converge even if you would use cents to decrease. perhaps you post a real sample for your amounts and how you want to compute the  values. that might us help to understand the 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
Question was answered..

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

From novice to tech pro — start learning today.