ä¸çªå³ç«¯ã®ç«ã£ã¦ãããããä½ç½®ãæ±ããããã®ããããã³ã¼ã
ä¸çªå³ç«¯ã®ç«ã£ã¦ãããããä½ç½®(RightMostBit)ãæ±ããã³ã¼ãã§éãã®ãªãããªã¼ã¨æ¢ãã¦ãããããã®ã£ã£ã£ãããã³ã¼ãã«åºä¼ã£ã¦ãã¾ã£ãã®ã§ãç´¹ä»ã2ch ã®ãããæ¼ç®ã¹ã¬ã§ 32bit å¤ã®ã³ã¼ãã«åºä¼ã£ã¦è¡æãåãã¦ããã®å¾ 64bit å¤çã®ãã³ããè¦ã¤ããã®ã§ã³ã¼ããæ¸ãã¦ã¿ã¾ããã
ãã®åé¡ã¯ ããã«ã¼ã®ãã®ãã¿âæ¬ç©ã®ããã°ã©ãã¯ããã«ãã¦åé¡ãè§£ãã (Google book search ã§åè Hacker's delight ãèªããã®ã§ããã§æ¸ã¾ãã) ã§ number of trailing zeros (ntz) ã¨ãã¦ç´¹ä»ããã¦ãã¾ããbit ã§èããã¨ãã«å³å´ã« 0 ãããã¤ããããæ°ãããã®ã1 ã 㨠0ã2 ã 㨠1ã0x80 ãªã 7ã12 ãªã 2 ã¨ãã£ããããã0 ã®ã¨ãã«è¡¨é¡ã©ããã®åé¡ã¨ãã¦èããã¨ããã¤ãè¿ãã®ï¼ã£ã¦ãã¨ã«ãªãã®ã§ãåé¡ãæ£ç¢ºã«ããããã« ntz ã¨ã㦠64 ãè¿ããã¨ã«ãããã ã¨æãã¾ããããã«æãã¤ãã®ãã«ã¼ãã§ 1bit ãã¤è¦ã¦ããæ¹æ³ã§ããããé«éåããæ¹æ³ã¯ãããã¤ãã¾ããï¼Hacker's delight ã§ã¯ãã¤ããªã¼ãµã¼ãã使ã£ã¦ã¦ãè¦ãã¨ãã¯ã¹ã²ã¼ã¨æã£ããã ãã©ããã®ã³ã¼ãã®åã§ã¯è²ããã¦è¦ãã¾ã(^^;
ã¡ãªã¿ã«ç°å¢ä¾åãã¦ãããªã x86/x64 ã« bsf (VC++ ãªã http://msdn.microsoft.com/en-us/library/wfd9z0bb.aspx) ã£ã¦ã®ãããã¾ããbsf ã§ã¯ 0 ã®ã¨ãã®æ»ãå¤ã¯æªå®ç¾©ã§ãã
åé¡ã®èª¬æã¯ããã¾ã§ã«ãã¦ãã³ã¼ãã®ç´¹ä»ã§ããHacker's delight ã®ã³ã¼ããã4ã5åéã(5-13ãã4ã5åã5-15ãã1.2ã1.3å)ãããã¦ãã¤ããå æ¸ãå端ãããªãï¼ããä¸ã¤ã§ 64bit å¤ä»¥ä¸ã®ãã¹ã¦ã®å¤ã«å¯¾å¿ã§ãã¾ãã
public static int GetNumberOfTrailingZeros( long x ) { if ( x == 0 ) return 64; ulong y = ( ulong ) ( x & -x ); int i = ( int ) ( ( y * 0x03F566ED27179461UL ) >> 58 ); return table[ i ]; }
table ã¯ä»¥ä¸ã®ããã«ãã¦æ±ãã¾ãã
static int[] table; table = new int[ 64 ]; ulong hash = 0x03F566ED27179461UL; for ( int i = 0; i < 64; i++ ) { table[ hash >> 58 ] = i; hash <<= 1; }
æå³ãããã¾ããï¼ï½
x & -x 㯠Hacker's delight ã«ãããç«ã£ã¦ããä¸çªå³ç«¯ã®ãããã ãæ®ãã¦0ã«ãã¦ãã¾ãé»éè¡ã使ããå ´é¢ãå¤ãã®ã§è¦ãã¦ããã¨ä¾¿å©ã§ããããããªå¤ãå
¥ãã¦ãããã¦ã¿ã¦ãã ããã
ãã®å¾ãå®å
¨ããã·ã¥ã使ã£ã¦æ°(2^n)ãæ°(0ã63)ã«å¤æãã¦ãããã§ãã0ã®ã¨ãã® if æãç®éãã§ããã0ã®ã¨ãå¼ã°ãªããªã© don't care ã§ããã°çãã¦ãOKã§ããçã㨠0 ã®ã¨ãã« 0 ãè¿ã£ã¦ãã¾ããbit1 æä¸ä½ããããç«ã£ã¦ããã¨ãã 0 ãªã®ã§åºå¥ã§ãã¾ããã64bit å¤ã®å³ç«¯ã®ãããä½ç½®ãããããã«ã¯ã0ã®å ´åãå«ããã¨65éãã®çããå¿
è¦ã§ããã65ããã¾ãè¶ããªãã³ã³ãã¯ããªããã·ã¥å¤ãä½ãã㨠if ãä¸è¦ã«ãªãã¾ãããã£ã¦ããã£ã¡ã®ã»ããéãå¯è½æ§ã¯ããã¾ããã
ãã®ã³ã¼ã㯠2ch ã®ãããæ¼ç®ã¹ã¬0x03 ã® 71 㨠80 ã§ç¥ãã¾ããã
http://pc12.2ch.net/test/read.cgi/tech/1226143920/
80 ãã解説ã®å¼ç¨ã®å¼ç¨ã
卿2^p-1ãããã®åããã£ã¦ãããããpããããåãåºãã¨ããªã¼ã«0以å¤ã®ãã¹ã¦ã®ãã¿ã¼ã³ãç¾ãã p=3ã®å ´åã®Mç³»åã¯ä¾ãã°ããã 0011101 â (卿2^3-1=7ã§åããã¿ã¼ã³ã®ç¹°ãè¿ã) 001110100111010011101... ä¸ã®æ¡ãã3ããããåãåºãã¨ã 001 (1) _011 (3) __111 (7) ___110 (6) ____101 (5) _____010 (2) ______100 (4) 1ã7ã¾ã§å ¨é¨åºãã ããããã«000ã ã追å ããã°ãï½ã ããã ãã ã¨é çªããã©ãã©ãªã®ã§ããã¼ãã«ã¨çµã¿åãããã (ä¸ç¥) ãããæº¢ãã«ãããã¹ã¯ãªã©ãçµã¿åããã¦ãããã
ããã¦ãTarZããã®è¦ã¤ããå¤ 0x03F566ED27179461 ã使ã£ãã®ãä¸ã®ã³ã¼ãã§ãã
http://slashdot.jp/~TarZ/journal/448559
0x03F566ED27179461 =
0000 0011 1111 0101 0110 0110 1110 1101 0010 0111 0001 0111 1001 0100 0110 0001ã
以ä¸å¼ç¨ã
ãã®ãããåã«ã¤ãã¦ã6æåãåãã ã使¥ã1æåç®ããé ã«è¡ã£ã¦ããã¨ã以ä¸ã®éãã«ãªãã
2ã¤ç®ã®ãã¿ã¼ã³ã§sortãã¦ã¿ãã¨ã000001ãã111111ã¾ã§ããã¹ã¦ã®ãã¿ã¼ã³ãåºç¾ãã¦ãããã¨ã確èªã§ããã
ããã«ããã«000000ãå ããã°ãã¹ã¦æããã¨ã«ãªãããªãã¨ç´ æ´ãããï¼
1 000001
2 000011
3 000111
以ä¸ç¥
ãããï¼ãããããï¼ãã®å¤ã¯ã©ããã£ã¦æ±ãããã ããï¼
( y * 0x03F566ED27179461UL ) >> 58 ã®é¨åã«ã¤ãã¦ããã¡ãã£ã¨æ¸ãã¦ããã¨ãy 㯠2 ã® n ä¹ã®å¤ãã¤ã¾ã 1, 2, 4, 8,... ã§æãç®ãããã¨ã«ãã£ã¦ 0x03F566ED27179461 ãå·¦ã·ãããããã¨ã«ãªãã¾ããy ã 1 ãªãã·ãããªãã2 ãªã 1bit ã·ããã4 ãªã 2bit ã·ããã¨ãã£ãããããããã«ãã£ã¦æ¡ããµããèµ·ãããä¸ä½ã®æ¡ãæ¶ãã¾ã(追è¨ããã®ã¨ã y ã®å¤ã«ãã£ã¦ä½ãããå·¦ã·ãããããå¤ããã®ã§ãï½ ã®å¤ã«ãã£ã¦ä¸ä½ 6bit ã®ããããã¿ã¼ã³ãå¤ããã¾ã)ãæå¾ã« 58bit (58=64-6) å³ã·ãããã¦ä¸ä½ 6bit ã®ããããã¿ã¼ã³ãä¸ä½ã«ç§»åã(ä¸ä½ bit ããã¹ã¯)ããã¼ãã«ãå¼ãã¾ãããã®ã¨ã符å·ä»ãæ´æ°ã使ãã¨ç¬¦å·æ¡å¼µããã¦ãã¾ããããã«ä¸ä½ 6bit ã® AND ãåãå¿ è¦ãããã¾ãã ulong ã使ããã¨ã§ãã®æéãåé¿ãã¦ãã¾ãã
åèãªã³ã¯
- http://slashdot.jp/~Tellur52/journal/448479
- http://slashdot.jp/~tarosuke/journal/448442
- http://slashdot.jp/~tarosuke/journal/448489 (æ°åã®æ±ãæ¹ï¼)
è±èªã§ã®è§£èª¬ãã¿ã¤ãã¾ããã
- http://www.0xe3.com/text/ntz/ComputingTrailingZerosHOWTO.html
- http://www-graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup (bité»éè¡ããã£ã±ã)
- http://citeseer.ist.psu.edu/leiserson98using.html (ãããæåã®è«æããªï¼)
- http://chessprogramming.wikispaces.com/De+Bruijn+sequence (æ°å¦ã«èå³ãããæ¹ã¯ãã¡ããè¦ãã¨æ¥½ãããã)
ãã¾ãããã®åé¡ãè§£ã IEEE754 ã® float ã使ã£ãããã¯ãããã¾ãããããã® 64bitç C# ã³ã¼ããæ¸ãã¦ã¿ã¾ãããä¸ã®ã³ã¼ãã®10åã»ã©é
ããªã£ã¦ãã¾ãã¾ããï¼ï¼
ç¦æã® unsafe 使ãã°éãããï¼
public static int FloatHack2( long v ) { if ( v == 0 ) return 64; v = v & -v; if ( v == -9223372036854775808 ) return 63; float f = ( float ) v; var bits = BitConverter.GetBytes( f ); uint n = BitConverter.ToUInt32( bits, 0 ); int r = ( int ) ( ( n >> 23 ) - 0x7f ); return r; }
(7/6追è¨) ããããã®ã¢ã¯ã»ã¹ãããã¨ããããã¾ãããããªããã¢ãã¯ãªè©±é¡ãªã®ã«ã¾ããã®ãããã¨ã³ããªã¼å ¥ãã«é©ãã¦ã¾ãw
æ¬å½ã«éãã®ï¼ã£ã¦ã¯ã¦ãã®ã³ã¡ã³ãã«çããã¨ãç°å¢ä¾åãã¦ãããã° x86 ã«ã¯ bsf ã¨ããæ©æ¢°èªããã£ã¦ä¸å½ä»¤ã§ã«ã¦ã³ãã§ãã¾ããx64 ã® 64bit ã§ããã° bsfqãç°å¢ä¾åãªããªããã®ã³ã¼ãã¯ç§ã®ç¥ãéãæéã§ããK8 ã§ã¯ bsf ãããã£ã¡ã使ã£ãã»ããããããã§ãã詳ããã¯ã³ã¡ã³ãåç
§ã64åã«ã¼ãããã®ã«æ¯ã¹ãã¨æå
ã®ç°å¢ã§ã¯10åç¨åº¦éãã§ããéãã«ãã ãã£ã¦ããããã¯ä¸ã¤åã®æ¥è¨ãããããã£ã¨éãã®ããã°æãã¦ãã ãããä¸ã«ã¯ä¸ãããï¼ããï¼
ã¡ãªã¿ã« Hacker's delight ã¯æ©æ¢°èªã«ããã¨ä½å½ä»¤å®è¡ãããã¨ã«ãªãã¨ãè«ãã¦ãæ¬ã§ãï½ åå²ãå²ãç®ãã§ããã ãé¿ãããããªãããããä¸çã
ã¯ã¦ãã®ããããªãã£ã¦ã³ã¡ã³ãã«çãã¦ä¸å¯§ã«èª¬æãã¦ã¿ã¾ãããã§ãããããªãã¦ãããã¨æãï½
- ç·¨éå±¥æ´
- 2009/7/6 ( y * 0x03F566ED27179461UL ) >> 58 ã®èª¬æãã¡ãã£ã¨ç´ãã¦ã¿ãããªã³ã¯1件追å ã追è¨è¿½å ã
- 2009/7/7 ãHacker's delight ã®ã³ã¼ããã4ã5åéããã ã£ãé¨åãä¿®æ£ã