I had the same problem. I needed to implement the so called Bankers' Rounding
Function, which would round with respect to the 4/5 rule. And finally I
ended doing it myself in a short Function in LO Basic. I tried my best,
although math and programming are not my strong sides. So here it is,
together with a Subroutine called "rounded_test" and the very Function is
called "Rounded".
Sub rounded_test
N=20.45454545454545454545
N= Rounded(N)
N=0
End Sub
REM Banker's Rounding Function
REM Accepsts parameter as Double with or without a sign +/-
REM Returns Double with or without a sign +/-,rounded to the second diggit
after the comma separator
Function Rounded (NumD As Double)
Dim NumI as Integer
Dim position as Integer
position=0
Dim overflow as Integer
overflow=0
Dim NumS as String
REM initilize 2 arrays (integer and string) and we save the number into them
NumS=Format( NumD, "0.################################################")
len01=LEN(NumS)
Dim Stringarray(len01-1) as String
Dim Integerarray(len01-1) as Integer
For i=1 to len01
string0=Mid(NumS,i,1)
If string0="." Or string0="," Then
Stringarray(i-1)="."
Integerarray(i-1)=0
position=i
Else
Stringarray(i-1)=string0
Integerarray(i-1)=Val(string0)
End if
next i
string0="" 'Emptying the variable which will be used to return the number -
string
REM Rounding
If position=0 Then 'an integer without a fraction part - return the number
as it is!
Rounded=NumD
Exit Function
Else
End If
If len01-position>2 Then 'will be rounding
For j=1 to len01-position-2 '(len01-position-2) number of diggits till the
end of the number string which will be dropped out
If Integerarray(len01-j)>5 Or overflow=1 Or (Integerarray(len01-j)=5 And
(Stringarray(len01-j-1)="1" Or Stringarray(len01-j-1)="3" Or
Stringarray(len01-j-1)="5" Or Stringarray(len01-j-1)="7" Or
Stringarray(len01-j-1)="9")) Then
overflow=1
If Integerarray(len01-j-1)+overflow<=9 Then
Integerarray(len01-j-1)=Integerarray(len01-j-1)+overflow
overflow=0
Else
Integerarray(len01-j-1)=0
overflow=1
End if
Integerarray(len01-j)=0
Stringarray(len01-j)="0"
Stringarray(len01-j-1)=CStr(Integerarray(len01-j-1))
Else
Integerarray(len01-j)=0
Stringarray(len01-j)="0"
End If
Next j
'If we have some left over, remaining after the removal of the exessive
diggits, we shall distribute it
'among the remaining integer and fractional part
If overflow=1 Then
For k=position to 0 step -1
If k=position-1 Then goto Lbl 'skip this if it is a comma or point
separator
If k=0 And (Stringarray(k)="-" Or Stringarray(k)="+") Then goto Lbl 'skip
this if it is a +/- sign
If Integerarray(k)+overflow<=9 Then
Integerarray(k)=Integerarray(k)+overflow
overflow=0
Else
Integerarray(k)=0
overflow=1
End if
Stringarray(k)=CStr(Integerarray(k))
Lbl: next k
Else
End If
'Check if we have a +/- sign in front
If Stringarray(0)="-" Or Stringarray(0)="+" Then
string0=Stringarray(0)
'If we have still some overflow remaining,
If overflow=1 Then
'We add 1 in front but, after the sign
string0=string0 & "1"
'Construct the remainder of the number
For i=2 to len01
string0=string0 & Stringarray(i-1)
next i
Else 'Without a sign in front
'Construct the remainder of the number
For i=2 to len01
string0=string0 & Stringarray(i-1)
next i
End If
Else
'If we have still some overflow remaining,
If overflow=1 Then
'We add 1 in front
string0=string0 & "1"
'Construct the remainder of the number
For i=1 to len01
string0=string0 & Stringarray(i-1)
next i
Else 'Without a sign in front
'Construct the remainder of the number
For i=1 to len01
string0=string0 & Stringarray(i-1)
next i
End If
End If
string0=Format( Val(string0),
"0.################################################")
len01=LEN(string0)
For i=1 to len01
string2=Mid(string0,i,1)
If string2="," Then Mid(string0,i,1)="."
next i
Rounded=Val(string0)
Else 'if the number is integer or has a fractional part with up to 2 diggit
after the comma separator, we return it as it is
Rounded=NumD
End if
End Function
You can call it for each line (item) in an invoice. It will take the number
you through at it and will return it rounded to the second diggit after the
comma or point separator. Then when you sum the invoice up - the numbers
will always be consistent and correctly rounded.
This is not the best of programming though, but it works.
I hope it will help someone.
Feel free to modify and use it as you please.
Cheers,
toodr
--
View this message in context:
http://nabble.documentfoundation.org/Visible-currency-rounding-tp4065342p4066292.html
Sent from the Users mailing list archive at Nabble.com.
--
To unsubscribe e-mail to: users+unsubscribe@global.libreoffice.org
Problems? http://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted
Context
- Re: [libreoffice-users] Visible currency rounding (continued)
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.