You are invited to Log in or Register a free Frihost Account!

# What is the problem with this function

imagefree
 Code: function dec2any( \$num, \$base=62, \$index=false ) {    if (! \$base )    {       \$base = strlen( \$index );    }    else if (! \$index )    {       \$index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,\$base );    }    \$out = "";    for ( \$t = floor( log10( \$num ) / log10( \$base ) ); \$t >= 0; \$t-- )    {       \$a = floor( \$num / pow( \$base, \$t ) );       \$out = \$out . substr( \$index, \$a, 1 );       \$num = \$num - ( \$a * pow( \$base, \$t ) );    }    return \$out; }

the following returns 00 while it should return 1000

 Code: dec2any(46656 , 36);

(i dont want to use base_convert because of its certain limitation, and this is the best what i got on the web. if you have better alternative or solution in mind, please suggest me).
jmraker
Here's some code that tests the function.

 Code: for(\$base = 2;\$base <= 36;\$base++){    for(\$a = 0;\$a <= 46656;\$a++){       \$t1 = base_convert(\$a, 10, \$base);       \$t2 = dec2any(\$a, \$base);       if(\$t1 != \$t2)          echo "Error: Number:\$a Base:\$base (\$t1) (\$t2)\n";    } }

and it generated
 Code: Error: Number:0 Base:2 (0) () Error: Number:0 Base:3 (0) () Error: Number:0 Base:4 (0) () Error: Number:0 Base:5 (0) () Error: Number:125 Base:5 (1000) (00) Error: Number:15625 Base:5 (1000000) (00000) Error: Number:0 Base:6 (0) () Error: Number:216 Base:6 (1000) (00) Error: Number:46656 Base:6 (1000000) (00000) Error: Number:0 Base:7 (0) () Error: Number:0 Base:8 (0) () Error: Number:0 Base:9 (0) () Error: Number:0 Base:10 (0) () Error: Number:0 Base:11 (0) () Error: Number:0 Base:12 (0) () Error: Number:0 Base:13 (0) () Error: Number:0 Base:14 (0) () Error: Number:0 Base:15 (0) () Error: Number:3375 Base:15 (1000) (00) Error: Number:0 Base:16 (0) () Error: Number:0 Base:17 (0) () Error: Number:0 Base:18 (0) () Error: Number:0 Base:19 (0) () Error: Number:0 Base:20 (0) () Error: Number:0 Base:21 (0) () Error: Number:0 Base:22 (0) () Error: Number:0 Base:23 (0) () Error: Number:0 Base:24 (0) () Error: Number:0 Base:25 (0) () Error: Number:15625 Base:25 (1000) (00) Error: Number:0 Base:26 (0) () Error: Number:0 Base:27 (0) () Error: Number:19683 Base:27 (1000) (00) Error: Number:0 Base:28 (0) () Error: Number:0 Base:29 (0) () Error: Number:0 Base:30 (0) () Error: Number:0 Base:31 (0) () Error: Number:0 Base:32 (0) () Error: Number:0 Base:33 (0) () Error: Number:35937 Base:33 (1000) (00) Error: Number:0 Base:34 (0) () Error: Number:0 Base:35 (0) () Error: Number:0 Base:36 (0) () Error: Number:46656 Base:36 (1000) (00)

So there's a problem with all numbers that should be 1,000,000, 1,000, and numbers that should be 0
jmraker
Found this interesting. I added this before the loop
 Code: \$digits = (log10( \$num ) / log10( \$base ));    var_dump(\$digits);    var_dump(floor(\$digits));

and got at that number \$digits happens to look like a whole number but there's something wrong when floor is used.
 Code: float(3) float(2)

Where the floor of 3 is 2
and the floor of 3 should be 3
 Code: \$a = 3.0; var_dump(\$a); var_dump(floor(\$a));

I might have fixed it by adding a tiny amount (0.000000000001) to each log10()
 Code: = 0; \$t-- ){       \$a = floor( \$num / pow( \$base, \$t ) );       \$out = \$out . substr( \$index, \$a, 1 );       \$num = \$num - ( \$a * pow( \$base, \$t ) );    }    if(\$out == '')       return \$index[0];    return \$out; } for(\$base = 2;\$base <= 36;\$base++){    for(\$a = 0;\$a <= 46656;\$a++){       \$t1 = base_convert(\$a, 10, \$base);       \$t2 = dec2any(\$a, \$base);       if(\$t1 != \$t2)          echo( "Error: Number:\$a Base:\$base (\$t1) (\$t2)\n");    } } ?>
imagefree
i have made 2 more functions (one for conversions from decimal to any between 2-62, and other is reverse). Please test it too.

 Code: function bconvert( \$tmp , \$base = 62 ) {    Global \$possible;    \$converted   = '';    for( ; \$tmp ; )    {       \$converted      = \$possible[\$tmp%\$base] . \$converted;       \$tmp         = floor(\$tmp / \$base);    }    return \$converted; } function rconvert( \$string , \$base = 62 ) {    Global \$possible;    //100001    //(2^5*1) + (2^4*0) + (2^3*0) + (2^2*0) + (2^1*0) + (2^0*1)    \$length   = strlen(\$string);    \$done   = 1;    \$return   = 0;    for(;\$length - \$done + 1 ; \$done++ )    {       \$return   += pow( \$base , \$length - \$done ) * strpos(\$possible,\$string[\$done-1] );    }    return \$return; } for(; \$start<=\$end; \$start++) {    \$bconvert      = bconvert(\$start , 62);    \$rconvert      = rconvert(\$bconvert , 62);            if( \$start != \$rconvert )    {       echo \$bconvert . '   ' . \$rconvert . '   ' . \$start . "\n";       echo 'false';       break;    } }
jmraker
They seem to work ok, even if you use
\$possible = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@\$^*()-_[]{}\|:;,./?`~%&+=<>';

and do base 90 (I improvised on the letters after Z)
imagefree
 jmraker wrote: They seem to work ok, even if you use \$possible = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@\$^*()-_[]{}\|:;,./?`~%&+=<>'; and do base 90 (I improvised on the letters after Z)

thanks for testing
Agent ME
It seems like you're trying to reinvent an encoding like base64, which is already implemented in php as base64_encode and base64_decode.
imagefree
 Agent ME wrote: It seems like you're trying to reinvent an encoding like base64, which is already implemented in php as base64_encode and base64_decode.

No i am just trying to base convert. base_convert() just allows the conversion upto base 36. i want some solution to extend it to max limit, but currently i am just successful in converting just base 10 to any base.
jmraker
The base64 functions are for converting binary data/files to ascii text, the base_convert function is for converting a number to a string with a different base like binary, octal, hex, etc. They use letters to represent numbers greater than ten.