PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (1): [1]

> Найдено сообщений: 3
stolmachev Отправлено: 07 Июля, 2015 - 08:52:28 • Тема: Ответы на вопросы из уроков по php • Форум: Уроки php

Ответов: 67
Просмотров: 4610
[quote=stolmachev][quote=EuGen]Урок № 5. Математические функции
обещанный вариант Конвертера систем счисления (к уроку №5):

PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. class Converter
  4. {       protected $cipherSet, $rgCiphers, $inputSet, $outputSet, $fromBase, $toBase, $iErrorCode, $sErrorMessage;
  5.  
  6.         function __construct($strSet)                           // Submit only full cipher set.
  7.         {       $this->cipherSet=$strSet;                               // Note: default initialization proc [constructor?]
  8.                 $this->iErrorCode=0;                                    // may be such: Init(), Converter() and __construct() !
  9.                 $this->sErrorMessage="";
  10.                 echo "<br> __construct( \"$strSet\" )";
  11.         }
  12.  
  13.         protected function baseArithmeticMult($fromBase)        //multiplication with non-decimal base
  14.         {       $currentResultLen=count($this->rgCiphers);
  15.                 if ($currentResultLen==0) {return;}
  16.                 $rgMods=array();
  17.                 $currentPos=0;
  18.                 $div=0;
  19.                 do  {$divided=0;
  20.                         if ($currentResultLen>$currentPos) {$divided=$this->rgCiphers[$currentPos]*$fromBase;}
  21.                         $divided+=$div;
  22.                         $rgMods[$currentPos]=$divided%$this->toBase;
  23.                         $div=(int)($divided/$this->toBase);
  24.                         $currentPos++;
  25.                         }
  26.                 while($currentResultLen>$currentPos||$div!=0);
  27.                 $this->rgCiphers=$rgMods;
  28.         }
  29.  
  30.         protected function baseArithmeticPlus($num)     //addition with non-decimal base
  31.         {       $currentPos=0;
  32.                 $divided=$num;
  33.                 do  {   $divided+=(int)($this->rgCiphers[$currentPos]);
  34.                                 $this->rgCiphers[$currentPos]=$divided%$this->toBase;
  35.                                 $divided=(int)($divided/$this->toBase);
  36.                                 $currentPos++;
  37.                         }
  38.                 while ($divided>0);                                             //??? it was erroneous while ($buf>0); +++++
  39.         }
  40.  
  41.         public function getErrorCode()                          //error's getters
  42.         {return $this->iErrorCode;}
  43.         public function getErrorMessage()
  44.         {return $this->sErrorMessage;}
  45.  
  46.         public function baseConvert($num, $fromBase=0, $toBase=0)       //main function
  47.         {       $num=(string)($num);
  48.                 $totalCiphers=strlen($num);                                                             // total Ciphers in $num
  49.                 $this->inputSet=substr($this->cipherSet, 0, $fromBase); // input Set - набор всех возм.цифр для вх.с.с.
  50.                 $this->outputSet=substr($this->cipherSet, 0, $toBase);  //output Set - набор всех цифр для вых.с.с.
  51.                 $this->toBase=$toBase;
  52.                 $this->rgCiphers=array();
  53.                 $this->iErrorCode=0;                                            // init was absent, need reset for next use of function +++++
  54.                 for ($currentPos=0; $currentPos<$totalCiphers; $currentPos++)   // цикл по всем цифрам конвертируемого числа
  55.                 {       $currentCipher=$num[$currentPos];               // current Cipher from current Pos of converting num
  56.                         $cipherSign=substr_count($this->inputSet, $currentCipher);  //cipher Sign - счётчик вхождений
  57.                                                                                                                                                 // подстроки(цифры) в строку исходной с.с.
  58.                         if($cipherSign==0)                                              // нет вхождений - нет такой цифры в исходном наборе с.с.
  59.                         {       $this->iErrorCode=254;
  60.                                 $this->sErrorMessage="Cipher '".$currentCipher."' not found in cipher set: ".$this->inputSet. " (iErrorCode=$this->iErrorCode)";
  61.                                 return null;
  62.                         }
  63.                         elseif($cipherSign>1)                                   // если входит больше 1 раза - исходный набор с.с. неверен
  64.                         {       $this->iErrorCode=255;
  65.                                 $this->sErrorMessage="Cipher '".$currentCipher."' found more than once in cipher set: ".$this->inputSet. " (iErrorCode=$this->iErrorCode)";
  66.                                 return null;
  67.                         }
  68.                         if ($currentPos>0)                                              // if ($currentPos!=0)
  69.                         {   $this->baseArithmeticMult($fromBase);
  70.                         }
  71.                         $this->baseArithmeticPlus(strpos($this->inputSet, $currentCipher));     //<-(позиция цифры во вход.наборе)
  72.                 }
  73.                 $convertedNum=''; $totalCiphers=count($this->rgCiphers);
  74.                 for ($currentPos=0; $currentPos<$totalCiphers; $currentPos++)
  75.                 {       $convertedNum=$this->outputSet[$this->rgCiphers[$currentPos]].$convertedNum;    // converted Num
  76.                 }
  77.                 return $convertedNum;
  78.         }
  79. }
  80.  
  81. function pres($n,$fb=10,$tb=2)                  // print results
  82. {       global $bc,$Npp;
  83.         $Npp++;                         // no serial must be external
  84.         echo "<br> $Npp) " ;
  85.         $res = $bc->baseConvert($n,$fb,$tb);
  86.         echo " baseConvert($n,$fb,$tb)= ", $res;
  87.         if ($bc->getErrorCode()<>0) echo " ",$bc->getErrorMessage();
  88. }
  89. $charset="UTF-8";                       //"Windows-1251";
  90. echo "  <html>
  91.                 <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=$charset\" />
  92.                 <title>My page in $charset</title>
  93.                 <link rel=\"stylesheet\" type=\"text/css\" href=\"wt.css\" />
  94.                 </head> <body>  ";             
  95. echo "<h3> Тест BaseConv: </h3> ";
  96. echo "<font color= blue face=Arial size=2> ";
  97.  
  98. $bc = new Converter("1223333444455555666666777777788888888999999999aaaaaaaaabcdefghi"); // test BAD Set !
  99. // $bc-> __construct();                 // such call is invalid !
  100. $n="1234567890"; $fb=10; $tb=8;// из 10-ричной - в 8-ричную
  101. $Npp=-1;
  102. pres($n,$fb,$tb);
  103. echo "<br>";
  104. $bc = new Converter("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
  105.  
  106. //$Npp=0;                                       // номер по порядку
  107. /*
  108. echo "<br>   ";         //VAR_DUMP("1А3"); echo "<br>   ";
  109. pres("1А3",10,10);                      // "русская А" недопустима
  110. pres("1A3",10,10);                      // "латинская А" допустима, но только в с.с. гораздо выше 10-тиричной
  111. pres("ABCD",16,10);                     // из ошибочно-16-ричной - в 10-ричную
  112. echo "</font> <br> ";
  113. pres("123",10,10);                      // нормальная, хоть и бессмысленная "конверсия" (для проверки)
  114. pres("ABCD",60,10);                     // из 60-ричной - в 10-ричную
  115. pres(7911519,10,60);            // из 10-ричной - обратно в 60-ричную
  116. pres(254);                                      // из 10-ричной - в 2-ичную (по умолчанию)
  117. pres(254,10,16);                        // из 10-ричной - в 16-ричную
  118. pres("254",10,17);                      // из 10-ричной - в 17-ричную
  119. pres("254",10,2);                       // из 10-ричной - в 2-ичную
  120. pres("254",8,2);                        // из 8-ричной - в 2-ичную
  121. pres("10111011",2,16);          // из 2-ичной - в 16-ричную
  122. pres("10111011",2,8);           // из 2-ичной - в 8-ричную
  123. pres("273",8,2);                        // из 8-ричной - обратно в 2-ичную
  124. pres("273",8,4);                        // то же из 8-ичной - в 4-ричную
  125. pres("10111011",2,4);           // то же из 2-ичной - в 4-ричную
  126. pres("10111011",2,3);           // то же из 2-ричной - в 3-ичную
  127. pres("abcd",16,10);                     // из 16-ричной - в 10-ричную
  128. pres("123",10,8);                       // из 10-ричной - в 8-ричную
  129. pres("1234567890",10,16);       // из 10-ричной - в 16-ричную
  130. pres("12345.67890",10,16);      // из 10-ричной - в 16-ричную - то же, но с дробью
  131. pres("1234567890",10,8);        // из 10-ричной - в 8-ричную
  132. */
  133. pres(254,10,16);                        // из 10-ричной - в 16-ричную
  134.  
  135. echo "</body> </html> ";
  136. ?>
  137.  

(Добавление)
[quote=stolmachev][quote=stolmachev][quote=EuGen]Урок № 5. Математические функции
Радость Ну, и чтобы поставить точку на этом Конвертере, предложу ещё свой вариант, который мне кажется короче и проще, особенно для начинающих:

PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. // Base_Conv2 =
  4. // расширение стандартного конвертора систем счисления (base_convert) до A-:-Z (до 61-ричной с.с.)
  5. // по умолчанию предполагается преобразование из 10-ной в двоичную с.с.
  6. // преобразует в 2 этапа: 1) из входной в 10-ную: $snum = сумма пар сомножителей (вес цифры * вес её разряда);
  7. // 2) из 10-ной - в выходную с.с.: цифры результата - это остатки от деления полученной суммы на основание
  8. // выходной с.с., взятые в обратном порядке (в цикле каждое следующее делимое - это целая часть частного от
  9. // деления, цикл выполяется до тех пор, пока частное не станет == 0).
  10. // заметка для себя: знак ^ - это НЕ СТЕПЕНЬ, а XOR!!
  11.  
  12. function base_conv2($num=0, $frombase=10, $tobase=2)
  13. {       $bastr="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  14.         if ($num==null | $frombase==null | $tobase==null) return NULL;
  15.         settype($num,"string");                                         // или $num=(string)($num);
  16.         $num=implode ("", explode(".", $num));          // вычленение "дробных" ТОЧЕК - всё к целому!
  17.         //echo "<br> base_conv2: Конверт. с.с.: число $num: ( $frombase -> $tobase ). <br>";
  18.         $fna = func_num_args();
  19.         $lnum=strlen($num); $nums=0;
  20.         for ($i=--$lnum; $i >= 0; $i--)
  21.         {       $ci=$num[$i];
  22.                 $posi=strpos($bastr, $ci, 0);
  23.                 if ($posi===FALSE)              {echo "Цифра $ci недопустима!<br>"; return "Err!";};
  24.                 if ($posi>=$frombase)   {echo "Цифра $ci вне диапазона $frombase-ичной с.с.!<br>"; return "Err!";};
  25.                 $pow=$lnum-$i; $plus=$posi*pow($frombase,$pow);
  26.                 $nums=$nums + $plus;
  27.         }
  28.         $num=$nums; settype($nums,"string");    // === конец 1-го этапа  === //
  29.  
  30.         if ($tobase==10) return $nums;                  // === 2-й этап. Если вых.с.с.=10-ичная, то результат уже готов === //
  31.         $nums="";
  32.         do      {$ci=$num%$tobase; $num=floor($num/$tobase); $sci=$bastr[$ci]; $nums=$sci.$nums;
  33.                 }
  34.         while ($num>0);
  35.         //
  36.         return $nums;
  37. }; // EOFunction base_conv2 ............................................................
  38.  
  39. echo "<h3> Tест Base_Conv2: </h3> ";    // далее - пару десятков проверок
  40. echo "<font color= blue> ";                             // выделение синим примеров с ошибками в аргументах
  41.  
  42. function pres($n,$fb=10,$tb=2)                  // PRint RESults - проверочная процедура
  43. {       global $bc,$Npp;
  44.         $Npp++;                                                         // номер п.п. д.быть внешней(глобал.)переменной
  45.         echo "<br> $Npp) " ;
  46.         $echores = " my Base_Conv2($n,$fb,$tb)=";
  47.         $res = base_conv2($n,$fb,$tb);
  48.         if (!$fb) $fb=10; if (!$tb) $tb=2;      // for php Base_Convert: 10 -> 2 (if absent)
  49.         $echosres = " * * * * * * * php Base_Convert($n,$fb,$tb)=";
  50.         $sres= base_Convert($n,$fb,$tb);        // а что ответит стандартная функция?
  51.         echo $echores, $res, $echosres, $sres;
  52. }
  53.  
  54. //$Npp=0;                                       // номер теста по порядку. в ПХП можно не "инициализировать" нулём :)
  55.  
  56. pres("1А3",10,10);                      // "русская А" недопустима (но Base_Convert игнорирует нелепые "цифры"!)
  57. pres("1A3",10,10);                      // "латинская А" допустима, но только в с.с. выше 10-ичной
  58. pres("ABCD",16,10);                     // из ошибочно-16- в 10-ичную (НО стандартный конвертер НЕ РАЗЛИЧАЕТ капс!)
  59. pres("123",10,10);                      // нормальная, хоть и бессмысленная "конверсия" (для проверки)
  60. pres("ABCD",60,10);                     // из 60-ричной - в 10-ичную
  61. pres(7911519,10,60);            // из 10-ичной - обратно в 60-ричную
  62. echo "</font> <br> ";
  63. pres(254);                                      // из 10-ичной - в 2-ичную (по умолчанию!)
  64. pres(254,10,16);                        // из 10-ичной - в 16-ричную
  65. pres("254",10,17);                      // из 10-ичной - в 17-ричную
  66. pres("254",10,2);                       // из 10-ичной - в 2-ичную
  67. pres("254",8,2);                        // из 8-ричной - в 2-ичную
  68. pres("10111011",2,16);          // из 2-ичной - в 16-ричную
  69. pres("10111011",2,8);           // из 2-ичной - в 8-ричную
  70. pres("273",8,2);                        // из 8-ричной - обратно в 2-ичную
  71. pres("273",8,4);                        // то же из 8-ичной - в 4-ричную
  72. pres("10111011",2,4);           // то же из 2-ичной - в 4-ричную
  73. pres("10111011",2,3);           // то же из 2-ричной - в 3-ичную
  74. pres("abcd",16,10);                     // из 16-ричной - в 10-ичную
  75. pres("123",10,8);                       // из 10-ичной - в 8-ричную
  76. pres("1234567890",10,16);       // из 10-ичной - в 16-ричную
  77. pres("12345.67890",10,16);      // из 10-ичной - в 16-ричную - то же, но с дробью
  78. pres("1234567890",10,8);        // из 10-ичной - в 8-ричную
  79.  
  80. ?>
  81.  
  82.  
stolmachev Отправлено: 07 Июля, 2015 - 02:16:15 • Тема: Ответы на вопросы из уроков по php • Форум: Уроки php

Ответов: 67
Просмотров: 4610
[quote=EuGen]Урок № 5. Математические функции

Евгений, Вы - гений.. но вариант решения, предложенный Вами, очевидно не проверен. Я за невероятные несколько дней ПОПЫТОК (безуспешных) понять Ваш алго-ритм "случайно" нашёл, как исправить процедуру: мне "кажется", я в ней (в классе Конвертера) нашёл пару ошибок (см. комменты справа в тех местах):

1.
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. class Converter
  4. ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...  
  5.  
  6.                 while ($buf>0); // --- [b]здесь неверная переменная $buf[/b]
  7. ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...  
  8.  
  9.                 for ($currentPos=0; $currentPos<$totalCiphers; $currentPos++)
  10.  
  11. ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...  
  12. // [b]где-то здесь надо бы ОБНУЛИТЬ переменную $this->iErrorCode, иначе после ошибки за всеми командами тянется её "наследство"[/b]
  13.                 {
  14.                         $currentCipher=$num[$currentPos];
  15.                         $cipherSign=substr_count($this->inputSet, $currentCipher);
  16.                         if($cipherSign==0)
  17.                         {
  18.                                 $this->iErrorCode=255;
  19.                                 $this->sErrorMessage="Cipher '".$currentCipher."' was not found in cipher set: ".$this->inputSet;
  20.                                 return null;
  21.                         }
  22.                         elseif...
  23. ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...   ...  
  24. ?>
  25.  

_________
Прошу прощения за наглость, но осмелюсь предложить исправленный вариант класса вместе с примерами его использования. Я, как новичок, потерял несколько дней, прежде чем сообразил, что со всем этим можно делать Не понял
stolmachev Отправлено: 24 Июня, 2015 - 10:00:52 • Тема: Юмор • Форум: Юмор

Ответов: 187
Просмотров: 12761
юмор "по теме":
на страничке http://www.php.su/php/intro/?7 читаем:
"Таким образом, запись '$y = ($x = 7)' равносильна записи '$x = 5; $y = 5;' "

Очевидно, автор-юморист тестит на внимательность? Улыбка

Страниц (1): [1]
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB