[intro to "Question of the moment"]
I’ve been a VB coder for years. I like it. Heck, I started programming in basic in 6th grade, when a friend and I used to sneak into the computer labs at the local university and try to do stuff on their system. (It was a VAX terminal hooked up to a mainframe or mini computer. I don’t recall all the details.)
At work, there’s been a lot of talk about converting everything to C#. So, since working on C# has been on the to-do list for quite a while, I’ve started working in it too. After about a week, it’s actually pretty easy to make the switch over from VB.Net. But then, most of my work is relatively straightforward console apps. Now, to make sure I know what I’m doing, I picked up a couple books from the library and started going through them. As I see things that seem interesting at any particular moment, I’ll post the topic and try to discuss it. I welcome any feedback.
[Today's questions]
A sample was given of declaring some decimal variables:
decimal d1; //sample 1 - good
decimal d2=50; //sample 2 - better
decimal d3 = 50M; //sample 3 - best
The problem with sample 1 is that you need to take the time to set d1 to a value later on. Might as well just do it now, as sample 2 shows.
The interesting one is sample 3. Does having the value explicitly entered as a decimal type make a difference. (That’s what the “M” does.) In memory, d2 may be equal to 50.000001, whereas d3 is definitely set to 50. No possiblility that their is a hanging decimal place way out in right field somewhere.
That’s what I’m interested in. Does it really make a difference?
Throwing together the simplest example possible (only key stuff included here):
decimal d2 = 50; //sample 2 - better
decimal d3 = 50M; //sample 3 - best
Console.WriteLine(“Sample 2: {0}”, d2);
Console.WriteLine(“Sample 3: {0}”, d3);
Gives a output of:
Sample 2: 50
Sample 3: 50
Looks like there is no difference. Now the interesting part.
Go open a Visual Studio command prompt, navigate over to the sample program, and open it up in ILDASM. Double click on the Main method to see the disassembly. Looking at the two lines of declaration, looks like they are the same:
//000013: decimal d2 = 50; //sample 2 - better
IL_0001: /* 1F | 32 */ ldc.i4.s 50
IL_0003: /* 73 | (0A)000010 */ newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0008: /* 0B | */ stloc.1
//000014: decimal d3 = 50M; //sample 3 - best
IL_0009: /* 1F | 32 */ ldc.i4.s 50
IL_000b: /* 73 | (0A)000010 */ newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0010: /* 0C | */ stloc.2
The lines in blue look identical to me, showing that the value is saved the same way each time.
Now, lets make it a little more interesting. lets set d3 to 50.0M to see if that makes a difference. Looking at the IL, it does something:
//000014: decimal d3 = 50.0M; //sample 3 - best
IL_0009: ldc.i4 0×1f4
IL_000e: ldc.i4.0
IL_000f: ldc.i4.0
IL_0010: ldc.i4.0
IL_0011: ldc.i4.1
IL_0012: newobj instance void [mscorlib]System.Decimal::.ctor(int32,
int32,
int32,
bool,
uint8)
IL_0017: stloc.2
Woah! something else is going on now. A quick search on Google led me to this discussion. Sounds like the Decimal overload is being used to ensure the decimal places aren’t lost, since the declaration is explicitly stating that there is a decimal place. (Gee, does that sentence even make sense?)
Where does that leave us? I don’t know. As I get to know some of this better, maybe I’ll be able to make more sense of it.
There was some more interesting reading here, and it shouldn’t be hard to find addition resources for this.