今天在匠人的博客看Duff's Device 发现一个链接,进去后看到好多经典的C语言代码...于是乎便摘下来分享下...
1 . 32位整型数的取反
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa) ;
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc) ;
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0) ;
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00) ;
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000) ;
...太复杂...没验证
2 . 计算32位整型数中1的个数
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
一样..没验证...
3 . 检测一个数是否为二进制数
b = ((n&(n-1))==0) ;
如果b为真,那个这个数就为二进制数,反之为非二进制数
(这个不怎么懂,不知道4&5后的结果是什么...)
4 . 把一个数的最后一位变为"0"
n=n&(n-1);
5 . Set the least significant N bits in a word.
~(~0<<n)
这个好像是把一个数的最后N位置"1",不过看不怎么懂
6 . 交换两个数的值
x = x & y ;
y = x & y ;
x = x & y ;
这里的的&是按位与运算,这个觉得太经典了,另外还可以简写成
x &= y &= x &=y;
7 . Convert a nibble into an ASCII hex digit.(这个看不懂,就把英文贴上来)
Another ancient one. I think I first saw it in the sources for 'vi', but it's probably a lot older than that.
"0123456789ABCDEF" [ n ]
(Where 'n' is in the range 0..15).
I have also seen this:
n [ "0123456789ABCDEF" ]
...which also works providing 'n' is a character variable and providing you turn off enough compiler error checking!
8 . 把所有非"0"的值变为"1"
b = !!a ;
如果a="0"那么b="0",否则b="1"
9 . 这个也不懂,贴英文贴英文
Some computers store integers with the most significant data in the first byte and the least significant data in the last, others do it the other way around. The former type are called 'big-endian' and the latter 'little-endian'. Intel computers are traditionally little-endian and most others big-endian.
Most people do not realise that the terms 'big-endian' and 'little-endian' come from Gulliver's Travels. The nations of Lilliput and Blefuscu were waging a terrible and bloody war over which end one should cut open on a boiled egg - the little end or the big end.
The war between CPU manufacturers is just as silly - and also pretty damaging.
Gulliver says: "...all true Believers shall break their Eggs at the convenient End: and which is the convenient End, seems, in my humble Opinion, to be left to every Man's Conscience, or at least in the power of the Chief Magistrate to determine."
Hmmmm.
Anyway, the way to decide which kind of machine you have is:
int i = 1 ;
little_endian = *((char *) &i ) ;
10 . Duffs Device
int a = some_number ;
int n = ( a + 4 ) / 5 ;
switch ( a % 5 )
{
case 0: do
{
putchar ( '*' ) ;
case 4: putchar ( '*' ) ;
case 3: putchar ( '*' ) ;
case 2: putchar ( '*' ) ;
case 1: putchar ( '*' ) ;
} while ( --n ) ;
}
printf ( "\n" ) ;
The loop prints the 'a' asterisks - but is 'unrolled' (which is important for speed in some applications). Most people are suprised that this even compiles.
It has been said that the worst problem with Duff's device is knowing how to indent it!
传说中很经典的东西,但是没怎么看懂.....以后强了再来慢慢寻味
用户1409644 2011-9-16 15:48
用户554377 2008-3-6 22:16