我只是想理解这段代码。
static int convert2binary(int Decimal)
{
int remainder, final = 0;
string result = "";
bool NaN;
while (Decimal > 0)
{
remainder = Decimal % 2;
Decimal /= 2;
result = remainder + result;
NaN = int.TryParse(result, out final);
}
return final;
}
它是一个二进制转换器,它到底是如何工作的?我只是不知道模数,十进制/= 2,然后将它们加在一起,如何得到二进制?
我们输入一些数据,好吗?
convert2binary(10)
-> remainder, final = 0
-> result = ""
-> NaN (= false)
loop:
Decimal > 0, so: remainder = Decimal % 2 (= 0) and Decimal /= 2 ( = 5)
result = remainder + result = 0 + ""
NaN = false
repeat:
Decimal > 0, so: remainder = Decimal % 2 (= 1) and Decimal /= 2 ( = 2)
result = remainder + result = "10"
NaN = false
repeat:
Decimal > 0, so: remainder = Decimal % 2 (= 0) and Decimal /= 2 ( = 1)
result = remainder + result = "010"
NaN = false
repeat:
Decimal > 0, so: remainder = Decimal % 2 (= 1) and Decimal /= 2 ( = 0)
result = remainder + result = "1010"
NaN = false
repeat: WHOOPS: Decimal == 0, so we return the final (int representation) of result.
现在,为什么这会起作用?
基本上,在每次迭代中,您都会从数字右侧分离出最后一个二进制数字(这是
%2
位)。由于您随后将其余部分除以 2(/=2
位),因此您可以循环执行此操作。
每次迭代都会为您提供数字多项式中的连续位置:
decimal(10) == 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0 = binary(1010)
你也可以朝另一个方向走:如果你想编写一个
int.ToString()
方法来打印数字的十进制变体,你可以用 % 10
分割最后一位数字(数字除以 10 的余数) ),这是要打印的最右边的数字。将其余部分除以 10,这样您就可以重复十位、百位等...
让我们试试这个!
int number = 123;
// this is equivalent to: (1 * 10^2) + (2 * 10^1) + (3 * 10^0)
int remainder = number % 10; // remainder = 3
number /= 10 // number = 12 (integer division!!)
result = remainder + ""; // result = "3"
// number is now: (1 * 10^1) + (2 * 10^0), because we divided by 10!
remainder = number % 10; // remainder = 2
number /= 10 // number = 1
result = remainder + result; // result = "23"
// number is now: (1 * 10^0)
remainder = number % 10; // remainder = 1
number /= 10 // number = 0 - we're going to STOP now!
result = remainder + result; // result = "123"
// yay! hurray!!
所以,你看,你的数字系统(无论是二进制、八进制、十进制、十六进制还是其他)只是写下基数幂多项式的简写。最右边的数字始终为基数^0,每向左移动一位数字,指数就会增加 1。
如果你弄清楚小数点的作用,就可以加分;)
请参阅本页的第二种方法:http://www.wikihow.com/Convert-from-Decimal-to-Binary
这就是你的算法正在尝试做的事情。
在十进制和二进制之间转换时,请记住每个二进制数字都是十进制中 2 的幂。
100110 = 1*2^5 + 0*2^4 + 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0 = 38
因此,要从整数构建二进制字符串,从右侧开始:
最后将该字符串转换为数字。
100110 = 1*2^5 + 0*2^4 + 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0 = 38
一个很多更清晰的思考方式是
2*(2*(2*(2*(2*(+1)+0)+0)+1)+1)+0 = 38
将基础的所有副本放在左侧,并将大端数字字符串拆分,每层一位数字,放在右侧。
这样可以更容易地在新的表示中看到原始的
100110
,同时避免重复工作,因为每个内层都受益于之前完成的乘法
采用类似的方法,某些 Merseene 素数也可以在此框架中表示:
2^(2^(2)-1)-1 => 2^(3) - 1 => 7
2^(2^(2^(2)-1)-1)-1 => 2^(7) - 1 => 127
2^(2^(2^(2^(2)-1)-1)-1)-1 => 2^127 - 1 => 170141183460469231731687303715884105727
以及 2 的通用幂
(
+0
是多余的,但包含在内是为了使它们与上面具有可比性):
2^(2^(2^(2^(2)-1)+0)+1)+0 => 2^257 => 231584178474632390847141970017375815706
539969331281128078915168015826259279872
和二进制平方算法就变成了:
2*(2*(2*(2*(2)^2)^2)^2)^2-1 = 2147483647 = (3-1)^31-1
3*(3*(3*(3*(3)^2)^2)^2)^2-4 = 617673396283943 = (3)^31-3-1