PC Review


Reply
Thread Tools Rating: Thread Rating: 1 votes, 1.00 average.

Currency Math in VB.NET

 
 
Mitchell Vincent
Guest
Posts: n/a
 
      11th Aug 2005
Just making sure I'm not missing the boat here, but are there any
special routines for doing currency math (fixed precision stuff) in .NET?

The wonderful problems of doing math on decimals tend to shine when
writing accounting software :-)

How are others dealing with this?

--
- Mitchell Vincent
- kBilling - Invoices Made Easy!
- http://www.k-billing.com
 
Reply With Quote
 
 
 
 
Lucvdv
Guest
Posts: n/a
 
      11th Aug 2005
On Thu, 11 Aug 2005 08:17:12 -0400, Mitchell Vincent
<(E-Mail Removed)> wrote:

> Just making sure I'm not missing the boat here, but are there any
> special routines for doing currency math (fixed precision stuff) in .NET?
>
> The wonderful problems of doing math on decimals tend to shine when
> writing accounting software :-)
>
> How are others dealing with this?


I think most work in double precision, truncate at 4 decimals, and transfer
the chopped off bits (accumulated) to their own account.


Seriously: I'm missing a currency type as well.

There's a workaround, but it induces a distinct feeling of going back in
time to COBOL.

Remember how you had to write an ADDONETOI subroutine to increment a
variable in COBOL? In .Net there's a currency datatype, but it knows no
operators + - / or *. No mixing of data types - you will NOT divide a
currency type by an integer, unless you yourself implement it as a
function.

Dim x1 As New SqlTypes.SqlMoney(0.0002)
Dim x2 As New SqlTypes.SqlMoney(0.0003)
Dim TWO As New SqlTypes.SqlMoney(2)
Dim x3 As SqlTypes.SqlMoney = SqlTypes.SqlMoney.Add(x1, x2)
Dim x4 As SqlTypes.SqlMoney = SqlTypes.SqlMoney.Divide(x3, TWO)
Debug.WriteLine(x4.ToString)

The result is 0.0003: standard rounding applied to .00025, whereas the
Math.Round function on a Double would, to many one's surprise, use banker's
rounding and say it's 0.0002. But that's topic for another discussion
 
Reply With Quote
 
Mitchell Vincent
Guest
Posts: n/a
 
      11th Aug 2005
Lucvdv wrote:

> Remember how you had to write an ADDONETOI subroutine to increment a
> variable in COBOL? In .Net there's a currency datatype, but it knows no
> operators + - / or *. No mixing of data types - you will NOT divide a
> currency type by an integer, unless you yourself implement it as a
> function.
>
> Dim x1 As New SqlTypes.SqlMoney(0.0002)
> Dim x2 As New SqlTypes.SqlMoney(0.0003)
> Dim TWO As New SqlTypes.SqlMoney(2)
> Dim x3 As SqlTypes.SqlMoney = SqlTypes.SqlMoney.Add(x1, x2)
> Dim x4 As SqlTypes.SqlMoney = SqlTypes.SqlMoney.Divide(x3, TWO)
> Debug.WriteLine(x4.ToString)
>
> The result is 0.0003: standard rounding applied to .00025, whereas the
> Math.Round function on a Double would, to many one's surprise, use banker's
> rounding and say it's 0.0002. But that's topic for another discussion



So you're using the SqlTypes.SqlMoney type for all your math operations?

It seems like the issue you just showed would be a reason not to!

I'm only in need of 2 precision, as I'm not dealing with anything
smaller than a cent.

Thanks!

--
- Mitchell Vincent
- kBilling - Invoices Made Easy!
- http://www.k-billing.com
 
Reply With Quote
 
Lucvdv
Guest
Posts: n/a
 
      11th Aug 2005
On Thu, 11 Aug 2005 09:53:12 -0400, Mitchell Vincent
<(E-Mail Removed)> wrote:

> So you're using the SqlTypes.SqlMoney type for all your math operations?


No, I got off lucky: I can use longs instead (no invoicing type of
applications, and all amounts I work with are multiples of 1 euro).

> It seems like the issue you just showed would be a reason not to!


That depends. In my opinion it's Math.Round that's giving the wrong
result, not the other one.

> I'm only in need of 2 precision, as I'm not dealing with anything
> smaller than a cent.


The currency type that exists in VB6 for example is also fixed 4 digits.

Over here we even have a law that stipulates that all computations on
currency values must be performed with an internal precision of 4 decimals
(0.0001 euros), and only the final printed results should be rounded to two
decimals.

As long as only addition and subtraction are used it's the same, but
percentages is where it begins to matter, and in Europe there's no way to
get around those (tax: the VAT nuisance).

It's perfectly possible here to have an invoice where the printed numbers
don't add up, if VAT amounts are listed per individual item (which is not a
requirement).
 
Reply With Quote
 
Jay B. Harlow [MVP - Outlook]
Guest
Posts: n/a
 
      11th Aug 2005
Mitchell,
I normally do all my "currency math" with System.Decimal, of course when I
use multiplication or division I need to be certain to round the numbers
"correctly".

In VB 2005 you can use Operator Overloading to define your own "special
routines" that handle any specific rounding issues, thus encapsulating any
possible rounding concerns. VB 2005's Operator Overloading also allows you
to leverage the overloaded operators on SqlMoney.

Hope this helps
Jay

"Mitchell Vincent" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
| Just making sure I'm not missing the boat here, but are there any
| special routines for doing currency math (fixed precision stuff) in .NET?
|
| The wonderful problems of doing math on decimals tend to shine when
| writing accounting software :-)
|
| How are others dealing with this?
|
| --
| - Mitchell Vincent
| - kBilling - Invoices Made Easy!
| - http://www.k-billing.com


 
Reply With Quote
 
Mitchell Vincent
Guest
Posts: n/a
 
      11th Aug 2005
Jay B. Harlow [MVP - Outlook] wrote:
> Mitchell,
> I normally do all my "currency math" with System.Decimal, of course when I
> use multiplication or division I need to be certain to round the numbers
> "correctly".


How do you handle it exactly?

I've always stored my money values as ints instead of fooling with the
decimal game but now that is more of a problem than a help.

I like the overloading idea - do you have any examples that I might go by?

Thanks a million!

--
- Mitchell Vincent
- kBilling - Invoices Made Easy!
- http://www.k-billing.com
 
Reply With Quote
 
Jay B. Harlow [MVP - Outlook]
Guest
Posts: n/a
 
      11th Aug 2005
Mitchell,
I use Math.Round & Decimal.Round most of the time.

..NET 2.0 (VS.NET 2005, due out late in 2005) has overloaded Math.Round to
account for other rounding methods (mid point up or even/bankers).

http://msdn2.microsoft.com/library/ms131274(en-us,vs.80).aspx


As suggested in the following previous post of mine, I find banker's
rounding (the current Math.Round function) to be the "logical" choice.

---x--- cut here ---x---
The way I understand it is:

Rather then always rounding the mid point up, "half of the time" you are
rounding it up & "half of the time" you are rounding it down.

The two "half of the time" together will average themselves out of the
picture.

When you always rounding the mid point up, then you start accumulating all
the fractions, rather then average them out...

The following demonstrates this:

Public Shared Sub Main()
Dim value1 As Decimal = 1.235D
Dim value2 As Decimal = 1.245D

Dim value3 As Decimal = value1 + value2

Dim value4 As Decimal = Decimal.Round(value1, 2) +
Decimal.Round(value2, 2)
Dim value5 As Decimal = RoundUp(value1, 2) + RoundUp(value2, 2)

Debug.WriteLine(value1, "value1")
Debug.WriteLine(value2, "value2")
Debug.WriteLine(value3, "value3")
Debug.WriteLine(value4, "value4")
Debug.WriteLine(value5, "value5")
End Sub

' may not handle negative value correctly...
Private Shared Function RoundUp(ByVal value As Decimal, ByVal decimals
As Integer) As Decimal
decimals = CInt(10 ^ decimals)
value *= decimals
value = Decimal.Truncate(value + 0.5D)
value /= decimals
Return value
End Function

Notice how value4 & value5 are off by 1, if you are lot of rounding, this
can add up significantly. When you use banking rounding, this difference
will not add up as quickly or as much...


---x--- cut here ---x---

| I like the overloading idea - do you have any examples that I might go by?
NOTE: You need C# 2002 or higher or VB 2005 or higher:

http://msdn.microsoft.com/library/de...verloading.asp

http://msdn.microsoft.com/library/de...ml/vs03h12.asp

http://www.panopticoncentral.net/arc...7/01/1338.aspx

Hope this helps
Jay

"Mitchell Vincent" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
| Jay B. Harlow [MVP - Outlook] wrote:
| > Mitchell,
| > I normally do all my "currency math" with System.Decimal, of course when
I
| > use multiplication or division I need to be certain to round the numbers
| > "correctly".
|
| How do you handle it exactly?
|
| I've always stored my money values as ints instead of fooling with the
| decimal game but now that is more of a problem than a help.
|
| I like the overloading idea - do you have any examples that I might go by?
|
| Thanks a million!
|
| --
| - Mitchell Vincent
| - kBilling - Invoices Made Easy!
| - http://www.k-billing.com


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to add new currency Symbol in Format/Cell/Currency NOORZAD Microsoft Excel Misc 2 22nd Jun 2009 07:59 AM
How Math.Cos & Math.Sin is implemented? Morgan Cheng Microsoft C# .NET 13 17th Oct 2006 04:03 AM
Currency Datatype Really Good to Use For Non-currency Fields? tbl Microsoft Access Database Table Design 4 10th Jul 2006 02:58 PM
excel math forumla? (simple math problem inside for math people!) Jason Microsoft Excel Discussion 3 16th Feb 2006 10:54 AM
Conversion from currency value to currency text format gdselva Microsoft Excel Programming 2 18th Aug 2004 10:06 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:45 AM.