FRIHOST FORUMS SEARCH FAQ TOS BLOGS COMPETITIONS
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:
<?php

function dec2any( $num, $base=62, $index=false ){
   if (! $base )
      $base = strlen( $index );
   else if (! $index )
      $index = substr( '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ,0 ,$base );
   $out = '';
   $digits = log10( $num ) / log10( $base ) + 0.000000000001;
   for ( $t = floor( $digits ); $t >= 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.
Related topics
Header("Location: PROBLEM");
ASP Problem
SMTP problem
[HELP] PC PROBLEM (don't bind)
terrorism in israel
PHP Problem: Unable to execute ext. commands
A minor printing problem
javascript function not being seen
Password problem
ODBC and PHP connections
(server 2) php function exif_read_data() not supported ?
problem with registration notify mod
Backup Storage Problem Further Isolated
ScanDir function problem
GOOGLE MAP: check nearest store where you located
Reply to topic    Frihost Forum Index -> Scripting -> Php and MySQL

FRIHOST HOME | FAQ | TOS | ABOUT US | CONTACT US | SITE MAP
© 2005-2011 Frihost, forums powered by phpBB.