A couple of little functions that someone might find useful.

Sometimes you need to do a division calculation but end up losing something!
For example, divide 10 by 3 to 2 decimal places. You get an answer of 3.33.
Fine, I am not going to quibble with that, except that if you then do 3.33 x
3, you don't end up with 10, you end up with 9.99. You've lost 0.01!

This might not seem important but if you are dealing with larger amounts and
those amounts are for example financial figures your accountant may want to
know where the missing money is!

So here is a little division function that simply splits the passed value
into the specified number of 'equal' chunks but such that nothing goes
missing (- so not necessarily equal then). It returns an array of values
that will always add up to give you the number you started with.

The return values will be to the same degree of accuracy as the passed value
that we are dividing, with the exception that if the passed value is an
integer it will default to 2 decimal places.

So for example, 10 divided by 3 will return the 3 values 3.33, 3.33 and 3.34

where as 10.1 divided by 3 will return 3.4, 3.3 and 3.3. Here the return
values are only to 1 decimal place because that is equal to the number of
places in the number 10.1. You may decide that you always want to return a
fixed number of decimal places though - please feel free to change the code!

The function calls a rounding function so here are the 2. You may have (and
would prefer to use) your own rounding function though which is why it is
separate.


//RoundToN is simply a rounding function that rounds a number to the given
number of decimal places.

Function RoundToN Global Number nRounding Integer iDecPlaces Returns Number
Move (10^iDecPlaces) to iDecPlaces
Move (nRounding * iDecPlaces) to nRounding
Move (Round(nRounding)) to nRounding
Move (nRounding / iDecPlaces) to nRounding
Function_Return nRounding
End_Function

//DivideWithNoLoss returns an array of values that always add up to the
number you started with - so you don't lose anything.

Function DivideWithNoLoss Global Number nNumToDivide Integer iDivideBy
Returns Number[]
Number[] nResults
Number nResult
Integer iDecPlaces iPos
String sNumToDivide

Move (String(nNumToDivide)) to sNumToDivide
Move (Pos(".",sNumToDivide)) to iPos
If (iPos<>0) Begin
Move (length(sNumToDivide)-iPos) to iDecPlaces
End
Else Move 2 to iDecPlaces

Repeat
Move (nNumToDivide/iDivideBy) to nResult
Get RoundToN nResult iDecPlaces to nResult
Move nResult to nResults[SizeOfArray(nResults)]
Move (nNumToDivide - nResult) to nNumToDivide
Decrement iDivideBy
Until (iDivideBy=0)
Move (SortArray(nResults)) to nResults

Function_Return nResults
End_Function


So

number[] nResults
Get DivideWithNoLoss 11.002 3 to nResults

will give you: 3.667, 3.667 and 3.668. Add 'em all up again and you're back
to 11.002


I have had this function for a while and forgot all about it. It is not
rocket science but someone somewhere (other than us) might find it useful -
you never know...


Peter Bragg