469,289 Members | 2,330 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,289 developers. It's quick & easy.

Using decimal type for money

Is decimal type a good choice to use for storing currency? I've got a
situation that when I store 8.50 in a decimal type variable and read it
back, I'm getting 8.5. Is there a better data type to store currency?

Thanks,
Gilgamesh
Nov 13 '05 #1
6 29738
Yes, it is intended to be used for money (currency).

You are 'getting back' "8.5" because there are built-in rules to say how a
number should be represented as a string. Look at String.Format for options.
For simple purposes, it won't matter whether you are using float, double, or
decimal, but the technicalities are that the decimal type can represent
decimal places exactly, whereas float and double types only approximate to
decimal values, so if you are doing complicated calculations then you can
get significant rounding errors if you don't use the right type.

S.

thewith the decimal type (presumably using ToStrGilgamesh
<gi*******@xteranet.com> wrote in message
news:Om**************@TK2MSFTNGP11.phx.gbl...
Is decimal type a good choice to use for storing currency? I've got a
situation that when I store 8.50 in a decimal type variable and read it
back, I'm getting 8.5. Is there a better data type to store currency?

Thanks,
Gilgamesh

Nov 13 '05 #2
Yes, can't find the OP now but I think it was that he was getting 8.5 back
because of using a float not a decimal, as you say decimal *happens* to
default to 2 dps (using the invariant culture anyway) but as you say you
could get 2 dps with either a float or a decimal by using String.Format.

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Simon Trew <ten.egnaro@werts> wrote:
Yes, it is intended to be used for money (currency).

You are 'getting back' "8.5" because there are built-in rules to say how a number should be represented as a string. Look at String.Format for
options.
I agree that using String.Format is the best way of going - but I'm
still somewhat surprised. I get 8.50 myself. For instance:

using System;

public class Test
{
public static void Main()
{
decimal d = 8.50m;

Console.WriteLine ("{0}", d);
}
}

prints 8.50.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too

Nov 13 '05 #3
For me it just printed:

8.5 8.5 8.5

What did you get?

S.

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Simon Trew <ten.egnaro@werts> wrote:
Yes, can't find the OP now but I think it was that he was getting 8.5 back because of using a float not a decimal, as you say decimal *happens* to
default to 2 dps (using the invariant culture anyway) but as you say you
could get 2 dps with either a float or a decimal by using String.Format.


No, it's not because decimal "defaults" to 2dps - decimal stores extra
information about how many 0s there are. Try this:

using System;

public class Test
{
public static void Main()
{
Console.WriteLine ("{0} {1} {2}", 8.5m, 8.50m, 8.500m);
}
}

Yes, it's bizarre.

I posted some code a while ago to "normalize" a decimal, by the way.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too

Nov 13 '05 #4
Simon Trew <ten.egnaro@werts> wrote:
For me it just printed:

8.5 8.5 8.5

What did you get?


8.5 8.50 8.500

Which version of .NET are you using?

If you disassemble the executable, what do you get in the IL for each
of them? I get:

IL_0005: ldc.i4.s 85
IL_0007: ldc.i4.0
IL_0008: ldc.i4.0
IL_0009: ldc.i4.0
IL_000a: ldc.i4.1
IL_000b: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0010: box [mscorlib]System.Decimal
IL_0015: ldc.i4 0x352
IL_001a: ldc.i4.0
IL_001b: ldc.i4.0
IL_001c: ldc.i4.0
IL_001d: ldc.i4.2
IL_001e: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0023: box [mscorlib]System.Decimal
IL_0028: ldc.i4 0x2134
IL_002d: ldc.i4.0
IL_002e: ldc.i4.0
IL_002f: ldc.i4.0
IL_0030: ldc.i4.3
IL_0031: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)

This was compiling with .NET 1.1, using just csc.exe.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Nov 13 '05 #5
Jon,
..NET 1.1 changed the Decimal type in this regard.

..NET 1.0 will report 8.5, 1.1 will report 8.50.

Its in the change lists on www.gotdotnet.com, however that site seems to be
down just now.

Hope this helps
Jay

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Simon Trew <ten.egnaro@werts> wrote:
For me it just printed:

8.5 8.5 8.5

What did you get?


8.5 8.50 8.500

Which version of .NET are you using?

If you disassemble the executable, what do you get in the IL for each
of them? I get:

IL_0005: ldc.i4.s 85
IL_0007: ldc.i4.0
IL_0008: ldc.i4.0
IL_0009: ldc.i4.0
IL_000a: ldc.i4.1
IL_000b: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0010: box [mscorlib]System.Decimal
IL_0015: ldc.i4 0x352
IL_001a: ldc.i4.0
IL_001b: ldc.i4.0
IL_001c: ldc.i4.0
IL_001d: ldc.i4.2
IL_001e: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0023: box [mscorlib]System.Decimal
IL_0028: ldc.i4 0x2134
IL_002d: ldc.i4.0
IL_002e: ldc.i4.0
IL_002f: ldc.i4.0
IL_0030: ldc.i4.3
IL_0031: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)

This was compiling with .NET 1.1, using just csc.exe.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too

Nov 13 '05 #6
I'm using 1.0, as you probably already guessed. I don't have a need to
upgrade right now.

S.

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Simon Trew <ten.egnaro@werts> wrote:
For me it just printed:

8.5 8.5 8.5

What did you get?


8.5 8.50 8.500

Which version of .NET are you using?

If you disassemble the executable, what do you get in the IL for each
of them? I get:

IL_0005: ldc.i4.s 85
IL_0007: ldc.i4.0
IL_0008: ldc.i4.0
IL_0009: ldc.i4.0
IL_000a: ldc.i4.1
IL_000b: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0010: box [mscorlib]System.Decimal
IL_0015: ldc.i4 0x352
IL_001a: ldc.i4.0
IL_001b: ldc.i4.0
IL_001c: ldc.i4.0
IL_001d: ldc.i4.2
IL_001e: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)
IL_0023: box [mscorlib]System.Decimal
IL_0028: ldc.i4 0x2134
IL_002d: ldc.i4.0
IL_002e: ldc.i4.0
IL_002f: ldc.i4.0
IL_0030: ldc.i4.3
IL_0031: newobj instance void [mscorlib]System.Decimal::.ctor
(int32, int32, int32, bool, unsigned int8)

This was compiling with .NET 1.1, using just csc.exe.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too

Nov 13 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Batista, Facundo | last post: by
11 posts views Thread by ZRexRider | last post: by
1 post views Thread by learning | last post: by
13 posts views Thread by =?Utf-8?B?RXRoYW4gU3RyYXVzcw==?= | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.