10進数から36進数を作る

  • デル株式会社
  • 最近はハードディスクの容量も飛躍的に上がって容量不足に悩むなんて事はシステム開発の現場でもなくなったけど、ひと昔前にそういった容量不足に対応する為にちょっとでも容量を節約する為にこんな事したなーなんてのを思い出したのでソース作っといたよ。
    中学校や高校では2進数とか16進数とか習ったと思うけど、システム開発の現場では36進数ってのは意外と世界中で通じたりするんだよ。Base-36って言ったりするよ。大文字小文字を分けて62進数ってのもあったりするよ。
    今でももしかすると役に立つ日が来るかも。DBの桁数増やしたいけど増やせない状況とか。そういう日がくると役に立つかも。ないか。ないね。

    一応OS関係なく動くようにがんばったつもり。

    #define DEF_BASE_DECIMAL (36)
    static const char decimalbase[36]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    void DecimalToBase36( const unsigned long long int x, char* z )
    {
    	if ( z == NULL ) return;
    
    	unsigned long long int xx = x;
    	unsigned long long int y;
    	unsigned long long int ymod;
    	char zwork[100]={NULL};
    
    	y = xx / DEF_BASE_DECIMAL;
    	ymod = xx % DEF_BASE_DECIMAL;
    
    	unsigned int ii ;
    	for ( ii = 0 ; ; ii++ )
    	{
    		zwork[ii]= decimalbase[ymod];
    		if ( y < DEF_BASE_DECIMAL ) break;
    		xx = y;
    		y = xx / DEF_BASE_DECIMAL;
    		ymod = xx % DEF_BASE_DECIMAL;
    	}
    	if ( y > 0 )
    	{
    		zwork[ii+1]=decimalbase[y];
    	}
    
    	size_t nLen = strlen(zwork)-1;
    	for ( ii = 0; ii < nLen; ii++ )
    	{
    		z[ii]=zwork[nLen-ii];
    	}
    	z[ii]=zwork[nLen-ii];
    
    }
    

    使い方。

    unsigned long long int mathx=0;
    char mathy[100] ={NULL};
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 35;
    /* Z */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 1295;
    /* ZZ */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 1296;
    /* 100 */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 1297;
    /* 101 */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 46655;
    /* ZZZ */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = 46656;
    /* 1000 */
    DecimalToBase36( mathx, mathy );
    
    memset( mathy, 0, sizeof(mathy) );
    mathx = ULLONG_MAX;
    /* 3W5E11264SGSF */
    DecimalToBase36( mathx, mathy );
    
    

    いつものことながら使うのは自己責任でね。
    DEF_BASE_DECIMALを62にしてdecimalbaseも62進数用にカスタマイズすれば62進数計算関数になると思うよ。やってみて。自分はやってないから知らんけどね。

    受け取り口をchar型にして作れば桁数制限なしにできると思うけど、さすがにそこまで必要なのは天文学の研究職くらいかな。。暇があったら桁数制限なしの36進数生成関数作ってみるけどいつになるかわからないよ。
    ULONGLONGの最大値は「18,446,744,073,709,551,615」、1844京、20桁だからふつうのお仕事してる開発者の人はこれで事足りると思うよ。

    次回は36進数から10進数をつくる関数。

    関連記事

    ページ上部へ戻る