这几天同学问了个问题,大致意思为用户会输入一个数(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<int> twoList = new List<int>();
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<int> 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<int> resultList = new List<int>();//用来存放按位除法的商
void Ten2Two(int[] num)
{
//用于存放获得的余数
List<int> twoList = new List<int>();
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<int> 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);
}