Date: | November 17, 2004 / year-entry #395 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20041117-00/?p=37283 |
Comments: | 20 |
Summary: | Warning: .NET content ahead. For some reason, this gets asked a lot. To break an integer into its component bytes, you can use the BitConverter.GetBytes method: int i = 123456; byte[] bytes = BitConverter.GetBytes(i); After this code fragment, the byte array contains { 0x40, 0xE2, 0x01, 0x00 }. Update 11am: The endian-ness of the result is determined... |
Warning: .NET content ahead. For some reason, this gets asked a lot. To break an integer into its component bytes, you can use the BitConverter.GetBytes method: int i = 123456; byte[] bytes = BitConverter.GetBytes(i);
After this code fragment, the byte array contains
Update 11am:
The endian-ness of the result is determined by
the
|
Comments (20)
Comments are closed. |
Perhaps stupid question: Why in little endian, or is it because of the platform you’re running it on?
.NET is supposed to be platform neutral — the code should return bytes in the same order irregardless of platform.
Little Endian is an interesting choice though.
When talking of bit representations of integers, the second issue (after endianness) is representation of negatives. Is it 2-complement or 1-complement?
|the code should return bytes in the
|same order irregardless of platform
This is exactly what I would have guessed, so if that’s true, the choice for little endianness would be a bit curious.
I was wondering the same as alfons when I saw this. Is AA’s explanation correct or is GetBytes platform specific and returning the bytes as they are stored in memory? The linked MSDN documentation seems a bit lacking – it makes no mention of what byte order to expect.
Why everybody looks so surprised being little endian the choice? What were you guys expecting? Network byte order? What byte order should be the appropiate for a "platform-independent" implementation?
Perhaps they come out big-endian on a big-endian machine. I don’t have access to one to find out.
The documentation for the BitConverter class has an "IsLittleEndian" static property. Presumably, you might want to check that value.
The very idea of looking at the bytes of a conceptual value is inherently platform-specific.
At least they give you some help with this static property.
.NET may (supposedly, theoretically) be platform independent, but 99.9999999% of the machines it runs on will be little-endian, so I don’t find it at all surprising that it was selected.
More to the point, you’re pulling bits out of your int – surely, that stinks of noodling around on the other side of the abstraction. Inquiring minds want to know: how does it handle negatives? I had the hardest time getting 2s complement ints out of Java, as it didn’t have a similar method. I mostly stuck the int into a long and did an if x<0, then x+=1<<31. Longs were harder.
int it = 23;
int twos = ~it – 1
isn’t it ?
One more reason to learn the basics and use a real programming language like C or C++, where the programmer actually has control over the real data
Don’t know crap about .net/C# so I may be wrong, but it looks to me that it only supports 2’s compliment by comparing the documentation for:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemint16classminvaluetopic.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemint16classmaxvaluetopic.asp
And looking at the mono source code, it looks like this does return it in whatever byte-layout the platform runs on.
You can check out the source of it here: http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/bitconverter_8cs-source.html (from the Microsoft SSCLI). I doubt that it is different in .NET v1.0 and v1.1. Maybe something is changed in .NET v2.0…
The rest of the answers is in the code ;)
(Btw. comparing the dissasembly of v1.0 vs v2.0(beta) of the class with with Reflector by Lutz Roeder; In v1.0 it is similar to the SSCLI(as expected), but in v2.0(beta!) it is just BitConverter.IsLittleEndian = true; …strange. But guess there is some #ifdef around the source code now instead.)
What I dislike about BitConverter is that it is a static class. Yeah sure, 99.9999% of machines .NET runs on are little endian. However there are plenty of binary files out there standardized on BigEndian. When parsing those files it sure would be nice to be able to create a "BigEndian" BitConverter but alas it can’t be done. Bummer. BTW,
Doh! Didn’t finish that last post. That same applies to BinaryReader and BinaryWriter.
Never mind 99.whatever % of machines. If Windows has to run on a bass-ackwards platform, the place to fix it would surely be in the hardware abstraction layer. That means 100% of machines running dotnet will be little-endian by the time anyone’s talking to the OS.
Of course, if you’re implementing dotnet on a non-Windows system, this is left as "an exercise for the student"
You can always do the bitconversion on your system(which gets it in the endianess of your system of course), and then convert it to network order when you need to send it (System.Net.IPAddress.HostToNetworkOrder).
I guess the rationale is that when you’re on a little endian system you should work in little endian too :) Maybe http://blogs.msdn.com/BCLTeam/ has the answer?
".NET is supposed to be platform neutral"
Only in theory, it’s meant to give the illusion that you can develop applications for Windows without vendor lock-in.
I however, see no reason whatsoever for MS to promote platform independent software, since that would hurt it’s strangle hold on the OS market.
Sure, there will be VM’s on other platforms, but will the essential API’s be available ?
Michael: -x = ~x + 1