C# 高,低位字节及多字节转换小结

1.查帖子偶然看到关于多字节转换,随笔记录小结,代码部分:

        private void button1_Click(object sender, EventArgs e)
        {
            //在 C# 中,BitConverter.ToUInt16 方法将按照小端字节序进行解析。
            //因此,在给定字节数组 temp 时,假设其按照小端字节序存储。则 temp[0] 是低位字节,temp[1] 是高位字节。
            //byte[] temp = new byte[] { 0x06, 0x01 };
            byte[] temp = new byte[] { 0x01, 0x06 };//temp[0]-0x01低位字节   ,temp[1]-0x06高位字节   =>综合就是0x0601==>十进制就是1537
            byte[] temp2 = new byte[] { 0x06, 0x01 };//temp[0]-0x06低位字节   ,temp[1]-0x01高位字节   =>综合就是0x0106==>十进制就是262
            pvValue[1] = BitConverter.ToUInt16(temp, 0);
            pvValue[2] = BitConverter.ToUInt16(temp2, 0);
            MessageBox.Show($"{pvValue[1]},{pvValue[2]}");

            //var shi1 = Convert.ToInt32("0x0601");//Wrong
            //在 C# 中,可以使用 Convert.ToInt32 方法将十六进制字符串转换为整数,例如:
            string hexString = "0x0601";
            int decimalValue = Convert.ToInt32(hexString, 16);
            //这个例子
<think>我们要求将ushort和short类型的值0x0001转换为小端字节数组。小端字节序:低位字节在前,字节在后。对于ushort和short,都是16位(2字节)整数。以ushortu=0x0001为例:字节是0x00,低位字节是0x01。小端序:先存储低位字节0x01,再存储字节0x00,即字节数组为[0x01,0x00]。同样,shorts=0x0001的转换方式相同,因为其内存表示在正数时与ushort相同(负数则不同,但0x0001是正数)。在C#中,我们可以使用以下方法:1.手动移位操作:将低8位放在数组第一个位置,8位放在第二个位置。2.使用BitConverter类:它会根据当前系统的字节序进行转换,如果系统是小端序,则直接使用;如果系统是大端序,则需要反转数组(但通常我们的系统都是小端序,所以可以直接使用,不过为了安全,可以检查并处理)。根据引用[2]和[3],我们可以使用BitConverter.GetBytes方法,但要注意系统的字节序。BitConverter.IsLittleEndian可以判断当前系统是否是小端序。如果是大端序系统,我们得到的是大端序的数组,此时我们需要反转数组来得到小端序?但注意:题目要求转换为小端字节数组,所以无论系统是什么字节序,我们都希望得到小端序的数组。因此,有两种思路:思路一:使用BitConverter.GetBytes,然后如果系统是大端序,则反转数组(这样得到的就是小端序数组)。思路二:手动转换,这样不依赖于系统字节序。但是题目要求小端字节数组,而小端字节序的定义是固定的:低位在前,位在后。所以我们可以直接手动转换,这样更直接,也不依赖于系统。我们分别用两种方法实现:方法1:手动转换(推荐,因为不依赖系统)ushortvalue=0x0001;byte[]bytes=newbyte[2];bytes[0]=(byte)(value&0xFF);//低位字节bytes[1]=(byte)((value>>8)&0xFF);//字节方法2:使用BitConverter,并确保结果是小端序byte[]bytes=BitConverter.GetBytes(value);//如果系统是大端序,那么BitConverter.GetBytes返回的是大端序,我们需要反转成小端序if(!BitConverter.IsLittleEndian){Array.Reverse(bytes);}//这样,无论系统是什么字节序,bytes都是小端序注意:题目要求的是小端字节数组,所以方法2中,当系统是小端序时,我们得到的就是小端序,不需要反转;当系统是大端序时,我们反转后变成小端序。然而,题目中要求的是ushort和short的0x0001,我们分别实现。但是注意:对于负数(short类型为负数)的转换,同样适用,因为移位操作和字节数组的构造是基于内存表示的。下面我们写两个方法,分别用于ushort和short的转换,并输出0x0001的转换结果。我们使用手动转换的方法,因为更直接且不依赖系统。步骤:1.对于ushort类型:byte0=(byte)(value&0xFF)byte1=(byte)((value>>8)&0xFF)2.对于short类型:同样操作,因为short在内存中也是2个字节转换方式相同。注意:0x0001的转换结果应该是:0x01,0x00。代码示例:</think>### C# ushort 和 short 转换为小端字节数组的方法 在 C# 中将 `ushort`(无符号短整型)和 `short`(有符号短整型)转换为小端字节数组时,需根据系统字节序进行处理。以下是两种可靠的方法: --- #### 方法 1:使用 BitConverter(自动处理字节序) ```csharp using System; public class EndianConverter { // 将 ushort 转换为小端字节数组 public static byte[] UshortToLittleEndian(ushort value) { byte[] bytes = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian == false) // 系统是大端则反转 Array.Reverse(bytes); return bytes; } // 将 short 转换为小端字节数组 public static byte[] ShortToLittleEndian(short value) { byte[] bytes = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian == false) // 系统是大端则反转 Array.Reverse(bytes); return bytes; } public static void Main() { ushort u = 0x0001; // 无符号示例 (1) short s = 0x0001; // 有符号示例 (1) byte[] uLittleEndian = UshortToLittleEndian(u); byte[] sLittleEndian = ShortToLittleEndian(s); Console.WriteLine("ushort 0x0001 小端: [{0}]", BitConverter.ToString(uLittleEndian)); Console.WriteLine("short 0x0001 小端: [{0}]", BitConverter.ToString(sLittleEndian)); } } ``` **输出示例**(小端系统): ``` ushort 0x0001 小端: [01-00] short 0x0001 小端: [01-00] ``` --- #### 方法 2:手动转换(不依赖系统字节序) ```csharp // 手动转换 ushort public static byte[] UshortToLittleEndianManual(ushort value) { return new byte[] { (byte)(value & 0xFF), // 低位字节在前(小端) (byte)((value >> 8) & 0xFF) // 字节在后 }; } // 手动转换 short public static byte[] ShortToLittleEndianManual(short value) { return new byte[] { (byte)(value & 0xFF), // 低位字节在前(小端) (byte)((value >> 8) & 0xFF) // 字节在后 }; } ``` --- ### 关键说明 1. **小端序原理** 小端序(Little Endian)要求低位字节存储在低地址,字节存储在地址: - `0x0001` 的二进制:`00000000 00000001` - 小端字节数组:`[0x01, 0x00]` 2. **BitConverter 的优势** - 自动检测系统字节序(通过 `BitConverter.IsLittleEndian`) - 系统是小端时直接返回,是大端时反转数组[^2][^3] 3. **手动转换的优势** - 不依赖系统环境,始终生成小端字节数组 - 适用于对性能要求的场景[^4] 4. **数值 0x0001 的处理** 无论使用哪种方法,`ushort 0x0001` 和 `short 0x0001` 都会转换为相同的字节数组 `[0x01, 0x00]`,因为它们的二进制表示在正数范围内相同[^4]。 --- ### 相关问题 1. 如何将小端字节数组还原为原始的 `ushort`/`short` 值? ```csharp // 从字节数组还原 ushort ushort FromLittleEndianToUshort(byte[] bytes) { return (ushort)(bytes[0] | (bytes[1] << 8)); } ``` 2. 如何处理 `uint`/`int` 等更大整数类型的小端转换? ```csharp public static byte[] IntToLittleEndian(int value) { return new byte[] { (byte)(value & 0xFF), (byte)((value >> 8) & 0xFF), (byte)((value >> 16) & 0xFF), (byte)((value >> 24) & 0xFF) }; } ``` 3. .NET Core 3.0+ 是否有更简洁的字节序处理方法? ```csharp // 使用 System.Buffers.Binary using System.Buffers.Binary; byte[] littleEndian = BinaryPrimitives.WriteUInt16LittleEndian(stackalloc byte[2], value); ``` 4. 当字节数组来自网络或文件时,如何确保正确解析? 应在通信协议中明确约定字节序,并在接收数据后验证 `BitConverter.IsLittleEndian`[^2][^4]。 [^2]: `BitConverter` 会根据系统字节序自动处理,但需注意跨平台兼容性 [^3]: 使用 `BitConverter.GetBytes()` 后检查 `IsLittleEndian` 可确保结果正确 [^4]: 手动转换不依赖系统环境,适合硬件通信等场景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值