关于C#转换二进制所引起的一些思考

2020-07-03 10:01:05于海丽

前言

最近遇到很有意思转换二进制的问题,有部分童鞋俨然已了解,可能也有一部分童鞋没碰到过也就不知情,这里我们来深入学习下转换二进制所带来的问题。

二进制转换问题

假设现在我们有一个int类型的数据,它的范围区间暂且定在0-15之间,我们需要将其转换为二进制,然后获取二进制中的每一位,若不足4位则0填充。看似很简单是不是,直接通过C#内置APi即可达到此需求,如下:

var binary = Convert.ToString(7, 2).PadLeft(4, '0').ToArray();

上述将数字7转换为包含二进制位的字符串数组形式,7转换二进制然后不足4位以0填充即(0111),我们如下获取二进制位字符串数组为索引的位,结果应该打印出0,对吗?

var zerobit = binary[0];
Console.WriteLine(zerobit);

好像一点毛病也没有,这是在控制台中进行打印,若是将该数据导出到Excel中,你会发现结果将可能是48或49而不是0或1(你可以一试)这是因为如下:

我们通过调试可知实际上在字符0上还携带有48,这个48实际上是字符0的ASCII码,字符1的ASCII码是49,通过如下代码即可证明:

foreach (var b in System.Text.Encoding.UTF8.GetBytes(binary))
{
 Console.WriteLine(b.ToString());
}

我们对将对应字符数组索引数据进行如下ToString转换即可避免导出数据时可能出现的问题

var zerobit = binary[0];
Console.WriteLine(zerobit.ToString());

转换字符数组问题

当我们转换为字符数组时,有两种方式,既可采用上述ToArray方法,也可以通过ToCharArray方法来实现,如下,那么哪种方法会更好呢?

var binary = Convert.ToString(7, 2).PadLeft(4, '0').ToArray();

var binary1 = Convert.ToString(7, 2).PadLeft(4, '0').ToCharArray();

此时比较此二者方法的性能好坏,只能去看对应源码实现,首先我们来看看ToCharArray方法,如下:

public unsafe char[] ToCharArray()
{
 if (Length == 0)
 {
  return Array.Empty<char>();
 }
 char[] array = new char[Length];
 fixed (char* smem = &_firstChar)
 {
  fixed (char* dmem = &array[0])
  {
   wstrcpy(dmem, smem, Length);
  }
 }
 return array;
}
internal unsafe static void wstrcpy(char* dmem, char* smem, int charCount)
{
 Buffer.Memmove((byte*)dmem, (byte*)smem, (uint)(charCount * 2));
}