Sharpmark's Personal Home Page

二进制数以及位运算

二进制数的一些特性

1、如果一个二进制数(整型)数的第零位的值是一,那么这个数就是奇数;而如果该位是零,那么这个数就是偶数。
2、如果一个二进制数的低端n位都是零,那么这个数可以被2n整除。
3、如果一个二进制数的第n位是一,而其他各位都是零,那么这个数等于2n。
4、如果一个二进制数的第零位到第n位(但不包含位n)都是一,而且其他各位都是零,那么这个数等于2n-1。
5、将一个二进制数的所有位左移移位的结果是将该数乘以二。
6、将一个无符号二进制数的所有位右移一位的结果等效于该数除以二(这对有符号数不适用)。余数会被下舍入(round down)
7、将两个n位的二进制数相成可能会需要2*n位来保存结果。
8、将两个n位的二进制数相加或者相减绝不会需要多于n+1位来保存结果。
9、将一个二进制数的所有位取反(就是将所有的一改为零,所有的零改为一)等效于将该数取负(改变符号)再将结果减一。
10、将任意给定个数的位表示的最大无符号二进制数加一的结果永远是零。
11、零递减(减一)的结果永远是某个给定个数的位表示的最大无符号二进制数。
12、n位可以表示2n个不同的组合。
13、数2年包含n位,所有位都是一。

有用的位运算

可以使用逐位与(and)运算来检测位串中的各个位是零还是一。例如:IsOdd = (ValueToTest & 1) != 0;

可以使用与运算来检测一组位是零/非零。例如IsDivisibleBy16 = (ValueToTest & 0xF) == 0;比较一个位串中的一组特定的位。(可能不连续)。

使用逻辑与创建模-n计数器(Modulo-n Counters)
cntr = (cntr + 1) & 0x3f; // 0×3f = 31. 这里实现的就是模-32计数器

主程序的异常处理结构

下面这段程序,实现了一个良好的main()函数结构。我这里解释一下他的功能和实现方法。
1、它处理整个程序的异常。整体框架被包括在一个try/catch结构里面。
2、它通过一个计数器restart,标记了之前运行得出错误数。这样在yourMain(int restart)中,就可以根据restart来判断这是第几次重新启动,并且可以做一些之前的异常情况的处理。
3、通过一个while来不断尝试重新开始程序。并通过标志位running来决定是否继续执行。
4、这里要注意几个问题,首先如果每次调用yourMain都会产生一个异常,这个结构就进入了死循环。你需要手动检查这是第几次运行,如果次数累计到一定程度,应该强制终止。
5、在捕获到异常,并重新调用yourMain的时候,全局或静态变量不会重新初始化。必须显式的重新初始化。

[code:c]
int yourMain(int restart)
{
// Your main function goes here.
}

int primaryMain()
{
int retval = 0;
bool running = true;
int restart = 0; // restart count
while(running)
{
try {
// Run the application
retval = yourMain(restart);

if (retval == 0) then running = false;
}
catch (std::exception& ex) {
// TODO: some error info ouput here.
restart++;
// Add code to decide if we should fail instead of restarting
}
catch(…) {
// TODO: some error info ouput here.
retval = 1;
running = false;
}
}

return retval;
}

int catchMain()
{
try {
// Run the application
return primaryMain();
}
catch(…) {
// TODO: some error info ouput here.
return 1;
}
return catchMain();
}

int main()
{
// TODO: set up something you need, like debug stream

return catchMain();
}[/code]

具体数学 - 约瑟夫问题

It seems a lot of stuff is attributed to Gauss…
either he was really smart or he has great press agent.
May be he just had a magnetic personality.

最近在看《具体数学 Concrete mathematics》,这是一本值得计算机相关专业任何年级的同学阅读的书。
第一章通过三个问题:The Tower of Hanoi; Lines in the Plane; The Josephus Problem. 前两个问题以前学习的深度已经够了,所以看了没有太大感觉,Josephus Problem的解决给了我很大的震撼。一个看似平常而无捷径的问题,通过用二进制表示,最终居然只要用一个循环移位就能解决。之后又扩展到 Josephus方程一般形式。其间,他的解题方法论很重要,以及其严谨的思路和发散的思维。
现列出书中第一章使用的解题方法:

  1. Look at small cases. This gives us insight into the problem and helps us in stages 2 and 3.
  2. Find and prove a mathematical expression for the quantity of interest.
  3. Find and prove a closed form for our mathematical expression.

已经翻译完成The Josephus Problem小节。对此感兴趣的点此下载(版本1.1.1,2007-12-23)。