�����餷����
2009-07-04 - ����C#��.NET�ʵ�Ͽ����������Ϥ����ޤǤˤ��ơ������ɤξҲ�Ǥ���Hacker's delight �Υ����ɤ��4��5��®���������ơ����ߥղø���Ⱦü����ʤ��������Ĥ� 64bit �Ͱʲ��Τ��٤Ƥ��ͤ��б��Ǥ��ޤ���
�Ǥ⡢�ºݤˤɤ줯�餤���Ϥ����뤫��Ƥߤ����ä��Τ�C�˰ܿ����Ƥߤ����ճ��ʷ�̤��ФƤ���ޤ���
0x03F566ED27179461ULL
�ޤ��Ϲ���ѡ�������Ѥäݤ����Ƥߤޤ�����
typedef unsigned long long U64; #define HASH 0x03F566ED27179461ULL static int ntzhash[64]; void init_ntzhash(){ U64 h = HASH; int i; for (i = 0; i < 64; i++, h <<= 1) ntzhash[ h >> 58 ] = i; } int ntz_hash(U64 n){ return n ? ntzhash[ (int)( ( ( n & -n ) * HASH ) >> 58) ] : 64; }
�����ե�
�Ǥ�ʥ����֤ʼ����Ǥ��͡�O(n)
int ntz_shift(U64 n){ int i; for (i = 0; i < 64; i++) if ( (n >> i) & 1 ) return i; return 64; }
��ʬõ��
Hacker's delight P. 85�˽ФƤ��ޤ���O(log n)��64bit�ξ��ǹ�8��ξ��ʬ���Ȥ������Ȥˤʤ�ޤ�������黻�Ҥ�Ȥä��������䤹���ΤǤ������ޤ�����
int ntz_bsrch( U64 n ) { n &= -n; return n == 0 ? 64 : n == 0x80000000ULL ? 31 : (n < 0x80000000ULL ? n == 0x8000ULL ? 15 /* 60�Ԥۤ���ά */ : (n < 0x4000000000000000ULL ? 61 : 63)))))); }
����ʤҤ����ɤ�������Τϼ�ǽ񤤤Ƥ����ʤ��Τǡ��ʲ���Perl Script�˼�ư�������Ƥ�餤�ޤ���(��use64bitint)��
sub foo{ my ($head, $tail) = @_; my $mid = int(($head + $tail) / 2); return $mid if $head >= $tail; my $ret = sprintf "n == 0x%xULL ? %d\n", 2**$mid, $mid; $ret .= sprintf ": (n < 0x%xULL ? %s\n: %s)", 2**$mid, foo($head, $mid-1), foo($mid+1, $tail); $ret =~ s/\n+/\n/g; $ret; } print foo(0,63)
frexp
n & -n
�ǡ�����̥ӥåȤ���Ω�Ƥ���Ȥ������Ȥϡ���Υ٥���ˤ��ǤˤʤäƤ���櫓�Ǥ�����������ɤ���äƥӥåȿ��˥ޥåפ��뤫��������ѤΤ������Ȥ����ʤΤǤ������⤦���������ߤΤʤ�������Ȥ��ơ�frexp()
��Ȥ��Ȥ���������⤢��ޤ���
#include <math.h> int ntz_frexp(U64 n){ int z; if ( n == 0 ) return 64; frexp( (double)( n & -n ), &z); return z - 1; }
x86��bsf̿��
�ǡ�x86��bsf̿���Ȥ�������Ǥ����ɤ�x86�Ǥ�ư���褦�������Ǥ�32bit�ʾ�ʤΤ��ݤ��Ǿ��ʬ�������Ƥ��ޤ���
int ntz_bsf(U64 n){ if (n == 0) return 64; unsigned int lo = n & 0xffffffff; int z; if (lo){ __asm__("bsf %1, %0;" :"=r"(z) :"r"(lo)); return z; }else{ n >>= 32; __asm__("bsf %1, %0;" :"=r"(z) :"r"(n)); return z + 32; } }
�ޤȤ�ƥ٥���ޡ���
�ǡ����Σ��Ĥ�ޤȤ�ƥ٥���ޡ������Ƥߤޤ����������˷����֤��������ꤹ��ȥ٥���ޡ���������ʤ���Хƥ��Ȥˤʤ�ޤ���Codepad�Ǥ�ư���ޤ�����
http://codepad.org/9UXR2cOu#include <sys/time.h> double time_hires(){ struct timeval now; gettimeofday(&now, NULL); return now.tv_sec + now.tv_usec/1e6; } #include <stdio.h> #include <stdlib.h> #include <assert.h> #define D63 ((U64)1 << 63) typedef struct { char *name; int (*func)(U64); } nfpair; static nfpair ntz[] = { {"ntz_shift", ntz_shift }, {"ntz_bsrch", ntz_bsrch }, {"ntz_frexp", ntz_frexp }, {"ntz_hash", ntz_hash }, {"ntz_bsf", ntz_bsf } }; int main (int argc, char **argv){ U64 n; int i, j, count = 0; double timer; if (ntzhash[63] != 6) init_ntzhash(); if (argc > 1){ /* benchmark */ count = (int)strtod(argv[1], NULL); for (j = 0; j < 5; j++){ timer = time_hires(); for (i = 0; i < count; i++){ assert(ntz[j].func(D63) == 63); } printf("%9s: %gs\n", ntz[j].name, time_hires() - timer); } }else{ /* test */ printf("%d\n", ntz_bsrch(D63)); for (j = 0; j < 5; j++){ for (i = 0, n = 1 ; i <= 64; i++, n += n){ assert(ntz[j].func(n) == i); printf("ok %d # %s(0x%016llx) = %d\n", ++count, ntz[j].name, n, ntz[j].func(n)); } } printf("1..%d\n", count); } return 0; }
�ǡ��ʲ�����̤Ǥ���
Core 2 Duo 2.4GHz, Mac OS X v10.5.7% gcc -W -Wall -O6 ntz.c && ./a.out 1e8 ntz_shift: 16.1367s ntz_bsrch: 1.8118s ntz_frexp: 2.79462s ntz_hash: 1.18244s ntz_bsf: 0.475164sDual Xeon 2.66GHz, FreeBSD 7.2
% gcc -W -Wall -O6 ntz.c && ./a.out 1e8 ntz_shift: 25.2944s ntz_bsrch: 1.65888s ntz_frexp: 7.1559s ntz_hash: 1.50684s ntz_bsf: 0.905658s
�٥���ޡ����ǻȤäƤ�����ͤϡ�O(c)�Ǥʤ����르�ꥺ��Ǻǰ��ˤʤ�褦��1<<63�ˤ��Ƥ���ޤ������Ƥ��̤ꡢ��ʬõ���ȹ���Ѥκ����ʳ��ȽФƤޤ���64bit�ξ軻�Υ����Ȥ��ʤ�....
���ޤ�
Perl�ΰ����Ϻ���Ȥ���ʤǤ��礦����0�ξ����б����Ƥ��ޤ��������Ϻ�γ�ˤ���ľ������....
sub ntz{ length(sprintf("%064b", shift) =~ /(0+)$/ && $1) }
Dan the Bit Counter
> n & -n�ǡ�����̥ӥåȤ���Ω�Ƥ���Ȥ������Ȥϡ���Υ٥���ˤ��ǤˤʤäƤ���櫓�Ǥ���
�����ʳ��� 0x08 �Ȥ��ˤʤ�ΤǤ���� 1 ������� 0x07 �Ǥ���0x07�ˤ�����1��Ω�äƤ���Τ�����Ȥ����ˡ�� Hacker's delight �ˤϽ񤤤Ƥ��ä����Ȼפ��ޤ����ġ�
frexp �䤽����ह�������ϡ�����������ư���������Ѵ�®��(�饤�֥��ʤΤ�CPU̿��ʤΤ��ϤȤ⤫���Ȥ���)�˶�����¸����Τǡ�����������������Ȼפ��ޤ���