Windows 10 64 位上双精度的字节序是什么?
What is the endianess of a double on Windows 10 64bit?
我正在使用 C# 并编写一个程序来通过 UDP 发送号码。我在 Windows 10 64 位平台上,我正在使用 BitConverter 从整数、双精度等中获取字节。
举个例子:
如果我使用:
Byte[] data = BitConverter.GetBytes((int)1);
我得到 01000000(十六进制),这将是预期的 little endian。
如果我使用:
Byte[] data = BitConverter.GetBytes((double)1);
我得到 000000000000f03f 十六进制,它看起来像一个 大端 数字,但我不太确定。
我的猜测是我对字节顺序或双格式没有很好的理解。我想 Windows 存储的双精度值也有可能不同于整数?
double 的二进制表示与整数的二进制表示不同。它遵循存储浮点值的 IEEE 标准。使用ieee标准,得到1的二进制表示,然后检查fir endianness。
一个有趣的笔记。您可能已经知道,C# 没有定义字节顺序,它依赖于 cpu 体系结构,如果您正在编写交叉 platform/architecture 应用程序,您可以检查方法调用 BitConverter.IsLittleEndian
Indicates the byte order ("endianness") in which data is stored in
this computer architecture.
Remarks
Different computer architectures store data using different byte
orders. "Big-endian" means the most significant byte is on the left
end of a word. "Little-endian" means the most significant byte is on
the right end of a word.
Note
You can convert from network byte order to the byte order of the host
computer without retrieving the value of the
BitConverter.IsLittleEndian
field by passing a 16-bit, 32-bit, or 64
bit integer to the IPAddress.HostToNetworkOrder
method.
如果您需要不同的字节序,您可以使用 Array.Reverse
轻松转换。
byte[] bytes = BitConverter.GetBytes(num);
Array.Reverse(bytes, 0, bytes.Length);
或使用 int
和 long
等类型的按位开关,您可以更进一步使用不安全和其他类型的指针
public uint SwapBytes(uint x)
{
x = (x >> 16) | (x << 16);
return ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
}
public ulong SwapBytes(ulong x)
{
x = (x >> 32) | (x << 32);
x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
return ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
}
当然是小端。
请记住,IEEE 浮点数是一个位域,符号的重要性高于指数,而指数的重要性又高于尾数。
您的整数示例只有一个字段,其低位已设置。
您的双精度示例在尾数字段中的所有位都是零,而指数位的更高有效字段是非零的。 (这两者都受到 IEEE-754 使用的偏置的影响)
有效位位于较高的内存地址,就像小端整数一样。
作为参考,1.0
的 IEEE-754 是 { sign: 0, exponent: 0x3ff, mantissa: 0x0000000000000 }
我正在使用 C# 并编写一个程序来通过 UDP 发送号码。我在 Windows 10 64 位平台上,我正在使用 BitConverter 从整数、双精度等中获取字节。
举个例子:
如果我使用:
Byte[] data = BitConverter.GetBytes((int)1);
我得到 01000000(十六进制),这将是预期的 little endian。
如果我使用:
Byte[] data = BitConverter.GetBytes((double)1);
我得到 000000000000f03f 十六进制,它看起来像一个 大端 数字,但我不太确定。
我的猜测是我对字节顺序或双格式没有很好的理解。我想 Windows 存储的双精度值也有可能不同于整数?
double 的二进制表示与整数的二进制表示不同。它遵循存储浮点值的 IEEE 标准。使用ieee标准,得到1的二进制表示,然后检查fir endianness。
一个有趣的笔记。您可能已经知道,C# 没有定义字节顺序,它依赖于 cpu 体系结构,如果您正在编写交叉 platform/architecture 应用程序,您可以检查方法调用 BitConverter.IsLittleEndian
Indicates the byte order ("endianness") in which data is stored in this computer architecture.
Remarks
Different computer architectures store data using different byte orders. "Big-endian" means the most significant byte is on the left end of a word. "Little-endian" means the most significant byte is on the right end of a word.
Note
You can convert from network byte order to the byte order of the host computer without retrieving the value of the
BitConverter.IsLittleEndian
field by passing a 16-bit, 32-bit, or 64 bit integer to theIPAddress.HostToNetworkOrder
method.
如果您需要不同的字节序,您可以使用 Array.Reverse
轻松转换。
byte[] bytes = BitConverter.GetBytes(num);
Array.Reverse(bytes, 0, bytes.Length);
或使用 int
和 long
等类型的按位开关,您可以更进一步使用不安全和其他类型的指针
public uint SwapBytes(uint x)
{
x = (x >> 16) | (x << 16);
return ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
}
public ulong SwapBytes(ulong x)
{
x = (x >> 32) | (x << 32);
x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
return ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
}
当然是小端。
请记住,IEEE 浮点数是一个位域,符号的重要性高于指数,而指数的重要性又高于尾数。
您的整数示例只有一个字段,其低位已设置。
您的双精度示例在尾数字段中的所有位都是零,而指数位的更高有效字段是非零的。 (这两者都受到 IEEE-754 使用的偏置的影响)
有效位位于较高的内存地址,就像小端整数一样。
作为参考,1.0
的 IEEE-754 是 { sign: 0, exponent: 0x3ff, mantissa: 0x0000000000000 }