[Tech]Trying to save Bytes may Byte you back!
Update: Just clarified a bit of stuff towards the end after a reread.
This tech post is long overdue, and has spent quite a lot of time in my drafts folder. I guess it's atlast time for it to see the light of day, so I'm posting it...
Lemme start off with code samples right away.
What's the output of this code snippet ?
Dim i as Int64 = 200
Console.WriteLine ( i.GetType.ToString )
Console.WriteLine ( (i-10).GetType.ToString )
Compile the code in your mind, and you'll find a lot of Syntax errors if you're a C# guy, and the following output if you're a VB guy:
System.Int64Pooh. Nothing unexpected. But, wait....What's the output of this code snippet ?
Dim b as Byte = 200
Console.WriteLine( b.GetType.ToString )
Console.WriteLine ( ( b -10).GetType.ToString)
So, just like in the last example, you should get System.Byte as the output both times, right ? Wah! I told you to wait, right ?
So, where did that System.Int32 come from? If an operation on an Int64 results in an Int64, then why is an operation on a Byte resulting in a System.Int32? Were the consipary theorists right, after all?
Oh wait! Lemme add one more to the mix!
What's the output of this ?
Dim s As Short = 200
Console.WriteLine( s.GetType.ToString )
Console.WriteLine( (s - 10).GetType.ToString )
If you've been sleeping all along, you would have expected two
System.Int16s, but ofcourse you weren't sleeping, so you'll see:
Uh-oh. So, what the hell is actually going on? So, to find out this, and some other things, I was digging through ECMA-355, the .NET ECMA Specs.
Aha! And, I fount out. The aptly named section 1.1.1 of the document says:
The CLI only operates on the numeric types int32 (4-byte signed integers), int64 (8-byte signed
integers), native int (native-size integers), and F (native-size floating-point numbers). However,
the CIL instruction set allows additional data types to be implemented:
Uh oh. So, what that means is, that the .NET CLI only knows about 32 Bit and 64 Bit Ints. When they say Native Int, they mean that if you implement .NET for a, say 16 bit Machine, then the CLI will "get" 16 bit Integers...
But wait, you say. The CLI already has 16 bit integers. Heck, it even has 8 bit integers!
But, ah I love to prove people wrong, and that's why I spent the time to read that headsy Technical Document. In the same old Section 1.1.1, it says:
Convert instructions that yield short integer values actually leave an int32 (32-bit) value on the stack, but it
is guaranteed that only the low bits have meaning (i.e., the more significant bits are all zero for the unsigned
conversions or a sign extension for the signed conversions).
Well, basically, what this means is, even if you use a Byte datatype[8 bits], you are still using 32 bits. Only that the 24 extra bits are Zero, always. They just lie there, useless, taking up precious memory space which could be used for some more 1s. Same for 16 bit ints: It still uses 32 bits, but only that 16 of those are not used and left zero.
When you see Short and Byte types in the Framework, they are just a mere illussion. They are still using 32 bits, just pretending that they're using less. That's why, the operations return the true type, rather than the illussionary one.
Update:Just thought that I'll add that the operation returns the true type, because the values are held on the Evaluation Stack while the operation[in this case addition] is being performed. Atleast, that's the reason I think. The normal GetType on the type gives you the illussionary type, because it's on the heap, not on the Evaluation Stack, which is real Harichandra v2.0.
Moral of the Story: Don't use Shorts and Bytes, if your sole reason is thinking that you're saving space: You are not....
Now, the best appreciation you could give to this small depressed kid living in a lone world surrounded by non-geeks with not many to talk to is to leave a comment here...
Technorati Tags: Byte, Bit, Wasted Bits, Wasted Memory, .NET, C#, VB.NET, Writing, Saving Space