回答:
RFCは、符号付き整数は、バイトがビッグエンディアンの方法で順序付けされた通常の4バイト整数であるとだけ言っています。
さて、あなたはおそらくリトル・エンディアンのマシンで作業していBitConverter.GetBytes()
て、byte[]
逆のことをするでしょう。だからあなたは試すことができます:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;
ただし、コードを最も移植性の高いものにするには、次のようにします。
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] result = intBytes;
byte[] result = intBytes;
?intBytes
必要な配列はまだありませんか?
result
です。このコードでは冗長です。ただし、結果がという名前の変数に含まれていることを理解できると想定するよりも、結果を明確に読者に示す方が教育的であると感じましたintBytes
。その上、メモリをコピーしたり新しいメモリを割り当てたりしないので、割り当てを行うことは安価です。すでに割り当てられている配列に新しい名前を追加するだけです。それで、なぜそれをしないのですか?
これを行う別の方法を次に示します。1xバイト= 8xビットを知っているため、「通常の」整数(int32)には32ビット(4バイト)が含まれます。>>演算子を使用してビットを右にシフトできます(>>演算子は値を変更しません)。
int intValue = 566;
byte[] bytes = new byte[4];
bytes[0] = (byte)(intValue >> 24);
bytes[1] = (byte)(intValue >> 16);
bytes[2] = (byte)(intValue >> 8);
bytes[3] = (byte)intValue;
Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}",
intValue, bytes[0], bytes[1], bytes[2], bytes[3]);
& 0xFF
ビットは不要です。
unchecked
ブロックでラップする必要があります。現在、コンパイラ設定で整数オーバーフローチェックが無効になっている場合にのみ機能します。
BitConverter.GetBytes(int)
エンディアンが間違っていることを除いて、ほとんどあなたが望むことをします。
Jon SkeetのEndianBitConverterクラスを使用または使用する前に、IPAddress.HostToNetworkメソッドを使用して整数値内のバイトを交換できます。どちらの方法も、移植性に関して正しいことを行います。BitConverter.GetBytes
int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
なぜ上記のサンプルのすべてのコードが...
明示的なレイアウトを持つ構造体は両方の方法で機能し、パフォーマンスに影響を与えません。
更新:エンディアンに対処する方法についての質問があるので、それを抽象化する方法を示すインターフェースを追加しました。別の実装構造体は、逆のケースを処理できます
public interface IIntToByte
{
Int32 Int { get; set;}
byte B0 { get; }
byte B1 { get; }
byte B2 { get; }
byte B3 { get; }
}
[StructLayout(LayoutKind.Explicit)]
public struct IntToByteLE : UserQuery.IIntToByte
{
[FieldOffset(0)]
public Int32 IntVal;
[FieldOffset(0)]
public byte b0;
[FieldOffset(1)]
public byte b1;
[FieldOffset(2)]
public byte b2;
[FieldOffset(3)]
public byte b3;
public Int32 Int {
get{ return IntVal; }
set{ IntVal = value;}
}
public byte B0 => b0;
public byte B1 => b1;
public byte B2 => b2;
public byte B3 => b3;
}
もう1つの方法は、BinaryPrimitivesを使用することです
byte[] intBytes = BitConverter.GetBytes(123);
int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);
using static System.Console;
namespace IntToBits
{
class Program
{
static void Main()
{
while (true)
{
string s = Console.ReadLine();
Clear();
uint i;
bool b = UInt32.TryParse(s, out i);
if (b) IntPrinter(i);
}
}
static void IntPrinter(uint i)
{
int[] iarr = new int [32];
Write("[");
for (int j = 0; j < 32; j++)
{
uint tmp = i & (uint)Math.Pow(2, j);
iarr[j] = (int)(tmp >> j);
}
for (int j = 32; j > 0; j--)
{
if(j%8==0 && j != 32)Write("|");
if(j%4==0 && j%8 !=0) Write("'");
Write(iarr[j-1]);
}
WriteLine("]");
}
}
}```
byte[] Take_Byte_Arr_From_Int(Int64 Source_Num)
{
Int64 Int64_Num = Source_Num;
byte Byte_Num;
byte[] Byte_Arr = new byte[8];
for (int i = 0; i < 8; i++)
{
if (Source_Num > 255)
{
Int64_Num = Source_Num / 256;
Byte_Num = (byte)(Source_Num - Int64_Num * 256);
}
else
{
Byte_Num = (byte)Int64_Num;
Int64_Num = 0;
}
Byte_Arr[i] = Byte_Num;
Source_Num = Int64_Num;
}
return (Byte_Arr);
}
Int16
。