十进制转二进制

这几天同学问了个问题,大致意思为用户会输入一个数(2-10之间的一个数的1024次方的值,也就是一个很大很大很大的数),问如何转换为二进制。

十进制转二进制的普通方法大家都知道,就是除以2取余数,得到的商进行递归,直到商为0。得到的余数倒序的结果即为对应的二进制,如

十进制78
78 ÷ 2 = 39 余 0
39 ÷ 2 = 19 余 1
19 ÷ 2 = 9  余 1
9 ÷ 2 = 4   余 1
4 ÷ 2 = 2   余 0
2 ÷ 2 = 1   余 0
1 ÷ 2 = 0   余 1 (商为0结束)
倒序得到 1001110 即为对应的二进制

对应的脚本为:

//使用 Ten2Two(78);

void Ten2Two(int num)
{
    //用于存放获得的余数
    List twoList = new List();

    Divide2AndGetRemainder(num, ref twoList);
    twoList.Reverse();

    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < twoList.Count; i++)
    {
        sb.Append(twoList[i]);
    }
    Debug.Log(string.Format("十进制数:{0} 转为二进制为: {1}", num, sb.ToString()));
    sb.Clear();
    sb = null;
}

void Divide2AndGetRemainder(int num, ref List list)
{
    if(num == 0)
    {
        return;
    }
    //添加余数
    list.Add(num % 2);
    //商递归
    Divide2AndGetRemainder(num / 2, ref list);
}

但是,这种做法是无法实现上面那个问题的,因为输入的数值很大,超过了long这些的上限,无法直接对这个值进行除2的处理。回归到除法的本质,多位数除以2,即从左到右,按位除以2,得到商即为最终结果对应位的数字,得到的余数则乘以10然后与下一位相加,例如:

十进制678

678 ÷ 2 即为 6 ÷ 2 = 3  余 0
            7 ÷ 2 = 3  余 1(十位的余数乘以10,与个位相加)
            18 ÷ 2 = 9 余 0(个位的余数即整个数字除以2的余数)
       得到 339 余 0

等价于

678 ÷ 2 = 339 余 0

然后递归下去。

所以对应上诉很大的数值,我们也按位进行处理,来获得它除以2的商和余数,代码如下(题目要求是C,这边就用C#写了,重点是思路)

//使用 Ten2Two(inputNum);
int[] inputNum = new int[] { 6, 7, 8, 9 };//假设这是用户输入的一个很大的数
List resultList = new List();//用来存放按位除法的商

void Ten2Two(int[] num)
{
    //用于存放获得的余数
    List twoList = new List();

    StringBuilder sb = new StringBuilder();
    sb.Append("十进制数: ");
    for (int i = 0; i < num.Length; i++)
    {
        sb.Append(num[i]);
    }

    Divide2AndGetRemainder(num, ref twoList);
    twoList.Reverse();
    
    sb.Append(" 转换为二进制为: ");
    for (int i = 0; i < twoList.Count; i++)
    {
        sb.Append(twoList[i]);
    }
    Debug.Log(sb.ToString());
    sb.Clear();
    sb = null;
}

void Divide2AndGetRemainder(int[] num, ref List list)
{
    if(num.Length == 0)
    {
        return;
    }

    resultList.Clear();
    for(int i = 0, len = num.Length, remainder = 0, result = 0; i < len; i++)
    {
        //加上 上一位余数*10
        num[i] += remainder * 10;

        //求商
        result = num[i] / 2;
        if (i == 0 && result == 0)
        {
            //如果第一位的商为0,则不写入商的数组中
            //例如101/2的结果为50,不是050
        }
        else
        {
            resultList.Add(result);
        }

        //求余数
        remainder = num[i] % 2;

        if(i == len - 1)
        {
            //最后一位的余数即为整个值除以2的余数,写入结果当中
            list.Add(remainder);
        }
    }

    //递归
    Divide2AndGetRemainder(resultList.ToArray(), ref list);
}

 

你可能感兴趣的:(乱七八糟,二进制,算法)