DUzun's Web
Programare, proiecte personale, divertisment

DUzun it's ME
 
/ 09 aprilie 2025, 01:00:09 /  
Conținut

LongNum.php

 
<?php
/*! ----------------------------------------------- *
 *  Clasa LongNum (Long Numbers)
 *  
 *  @Author: Dumitru Uzun (DUzun)
 *  @Web   : http://duzun.teologie.net/
 *      
 * 
 *  ----------------------------------------------- */
/*------------------------------------------------------------------------*/
include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'PkInts.php');
/*------------------------------------------------------------------------*/
class LongNum extends PkInts
{
    /* $radix indica baza in care se reprezinta numarul la convertirea in/din STRING.
     * La convertirea in numar, $radix == 1 indica date binare (fara transformare).
     * Simbolurile cifrelor sunt cifrele zecimale si literele alfabetului Englez (36 simboluri).  
     */     
    //static $digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    static public $radix = 10; // baza implicitta
    static public $carry = 0;          // Valoarea de transport
  
/*------------------------------------------------------------------------*/
    /*! Obtine cifra pentru valoarea $nm (in baza 36) */
    static function val2digi($nm) 
    {
       //return self::$digits[$nm];
       return chr((($r=$nm+0x30)>0x39)?($r+0x07):$r) ;
    }
    
    /*! Obtine valoarea cifrei $ch (in baza 36) */
    static function digi2val($ch)
    {
       //return strpos(self::$digits, strtoupper($ch));
       $ch = ord($ch[0]);
       if(0x2F<$ch && $ch<0x3A) return $ch-0x30; // cifrele zecimale  
       $ch |= 0x20; // fortam minuscula
       if(0x60<$ch && $ch<0x7B) return $ch-0x57; // alfabetul latin  
       return false; // nu exista asa cifra
    }   
    
    /*! Incearca sa ghiceasca baza numarului din reprezentarea $str
     *  Daca sunt caractere straine, $str se considera binar.
     *  Daca incepe cu '0x', baza e 16.     
     *  Daca incepe numai cu '0', baza e 8.
     *  Daca incepe cu '$', baza e 2.
     *  Daca sunt numai cifre zecimale, baza e 10.          
     */
    static function guess_radix($str)
    {
       if(!strlen($str) || preg_match('#[^\s\+\-\$0-9A-Z]#i', $str)) return 1; // binarry data
       $p = 0;
       while(preg_match('#^\s\+\-#', $str[$p])) $p++;
       switch($str[$p])
       {
          case '0': if($str[$p+1] == 'x') return 16;
                    return 8;
          case '$': return 2;
          default:  if(!preg_match('#[^0-9]#', $str)) 
                   return 10;
       }
       return false;
    }      
/*------------------------------------------------------------------------*/
    /*! $val - valoarea, $radix - baza lui $val.
     *  $radix == 1 - pentru $val date binare
     */ 
    function __construct(/*[$val=0[, $radix]]*/)
    {
       parent::__construct();
       if(func_num_args())
       {
          if(func_num_args() > 1) {
            $radix = (int)func_get_arg(1);
            if( 2 <= $radix && $radix <= 36 ) $this->radix = $radix;
          }
          else $radix = 0;
      
          $val = func_get_arg(0);
          if($radix) $this->set_val($val, $radix); 
          else       $this->set_val($val);
       }
    }  
       
    function __toString()
    {  
        return $this->get_str();
    }
    /*------------------------------------------------------------------------*/
    protected function get_radix()
    { // Se apeleaza automat prin getter
       return self::$radix;
    }
    /*------------------------------------------------------------------------*/
    /*!
     * Valoarea string a obiectului este reprezentarea numarului in baza $radix.
     * Daca $unsigned == TRUE, numrul se interpreteaza ca fara semn.     
     */ 
    public function get_str($radix=false, $unsigned=false)
    {
       if(!$radix) $radix = $this->radix;
       $rev = $radix < 0 ? $radix = -$radix : false;
       if($radix == 1) return $rev ? strrev($this->data) : $this->data;
       $l = strlen($this->data);
       if($l==0) return '0'; // '0' e zero in orice baza
       
       $data = $this->data; // copie de rezerva a datelor
       if($unsigned || !$this->get_sign()) $s = 0;
       else
       {
          $s = -1;
          $this->negative();
       }
       switch($radix)
       {
          case 2:
             $r = rtrim($this->get_bits(), '0 '); // ordinea inversata (din mem) 
             $rev = !$rev;
             if($s) { $r .= '-'; $s = 0; }
          break;
          case 16: 
             $r = '';
             $p = $this->not_null_r();   // stim la sigur ca numarul e pozitiv
             do $r .= bin2hex($this->data[$p]); while($p--);
             $r = ltrim($r, '0');
          break;
          
          default: 
             $r = '';
             //if(!( $radix & ($radix - 1) )) {} // baza 2^n ???
             while(!$this->is_null())
             {
               $this->div_int($radix);                 // impartim numarul la baza
               $r = self::val2digi(self::$carry) . $r; // restul impartirii este ultima cifra
             }
       }
       $this->data = $data; // restabilim datele
       if(empty($r)) return '0';
       if($s) $r = '-'.$r;
       return $rev ? strrev($r) : $r;
    }
    
    /*------------------------------------------------------------------------*/
    /*! 
     *  Daca $radix == 0, se foloseste baza $this->radix.
     *  Daca $radix == 1, $op sunt date binare.
     *  Daca $radix e o baza valida, $op reprezinta inscrierea 
     *  unui numar in baza $radix.           
     */
    public function set_str(&$op, $radix = 0)
    {
       if(!is_string($op)) $op = strval($op);
       if( $radix < 0 ) {
          $radix = -$radix;
          $op = strrev($op);
       }
       
       if($radix == 0) {
          $r = self::guess_radix($op);
          $radix = $r ? $r : self::default_radix;
       } 
       elseif($radix == 1) $this->data = $op; else
       {
          $this->data = '';
          if($op[0] == '-') $s = true;
          $op = ltrim(str_replace(' ', '', $op), '-+$');
          $l  = strlen($op);
          $v = 0;
          
          if(!( $radix & ($radix - 1) ))                   // Baza 2^n
          {
             $r = max_log2($radix);                        // nr de biti pu o cifra $radix
             $o = 0;
             while($l--)                                   // nr se parcurge invers, deoarece in memorie se reprezinta invers
             {
               $d = self::digi2val($op[$l]);
               if($d === false || $d >= $radix) continue;  // cifra inacceptabila
               $v += $d << $o;                             // acumulatorul valorii
               for($o+=$r; $o>=8; $o-=8, $v>>=8)           // $o - acumulatorul nr de biti
                  $this->data .= chr($v & BYTE_MASK);
             }
             if($v) $this->data .= chr($v);
          }
          else                                             // Baza oarecare, cazul general
          {
             $r = floor(log(INT_LO_MASK, $radix));         // nr de cifre in baza $radix ce incap in jumate de INT
             if($l < 2*$r)                                 // pentru numere mice nu are rost de pierdut timpul cu inmultiri
             {
               for($i=0; $i<$l; $i++) {
                 $d = self::digi2val($op[$i]);
                 if($d === false || $d >= $radix) continue;// cifra inacceptabila
                 $v *= $radix; $v += $d;                   // acumulatorul valorii
               }
               $this->set_int($v);
             }
             else
             {
               $m = pow($radix, $r);                       // baza pu $r cifre grupate
               $o = $r;                               
               for($i=0; $i<$l; $i++)
               {
                 $d = self::digi2val($op[$i]);
                 if($d === false || $d >= $radix) continue;// cifra inacceptabila
                 $v *= $radix; $v += $d;                   // acumulatorul valorii
                 $o--;                                     // numaratorul cifrelor bazei $radix
                 if(!$o) {
                   $this->mul_int($m);
                   $this->add_int($v);
                   $v = 0; 
                   $o = $r;
                 }
               }
               if($v) {                                    // nu a fost adaugata valoarea $v la numar
                 $this->mul_int(pow($radix, $r-$o));
                 $this->add_int($v);
               }
             }
          }
          $this->data .= NULL_CHAR;                        // reprezentarea totdeauna este nr pozitiv
          if(!empty($s)) $this->negative();
       }
       return $this->get_val();
    }
        
    /*------------------------------------------------------------------------*/
    /* Important:
     *   $by trebuie sa fie atat de mare, incat ($by-1) * 256 + 255 <= PHP_INT_MAX,
     *   de unde avem: $by <= (INT_MAX-255) / 256 + 1 = (INT_MAX >> 8) + 1
     */
    public function div_int($by)
    {
       if($by == 0) { return self::$carry = -1; } 
       if($s = $by < 0)  // !!! exceptia!
       {
          $this->negative(); 
          $by = -$by; 
       }  
       self::$carry = 0;
       if($by > 1)
       {
          $o  = &self::$carry;
          $dt = &$this->data;
          $l  = strlen($dt);
          while($l--)
          {
             $g = ($o << 8) | ord($dt[$l]);  // transportul de la octetul precedent + octetul curent
             $o = $g % $by;                  // transportul pentru urmatorul octet
             $dt[$l] = chr(($g-$o) / $by);   // catul impartirii
          }
       }
       return $this->get_val();
    } // div_int
    
    /*------------------------------------------------------------------------*/
    /* Important:
     *   Analogic cu div_int, $o <= INT_MAX, de unde avem:
     *     $by <= (INT_MAX-(INT_MAX / 256)) / 255 = (INT_MAX >> 8) + 1
     */
    public function mul_int($by, $null_check=true)
    {
       // 0 * x = 0, for any x
       if($by == 0) { $this->data = ''; return 0; }
       if($null_check && $this->not_null() === false) return 0;
//        $this->reduce(); // sa presupunem ca algoritmii precedenti au grija de acest lucru
       $s = $by & INT_SIGN; 
       $o = $this->get_sign();
       if($o) {
          $this->negative();
          $s = ($s xor $o);
       }
       if($s) $by = -$by;      // de cazul -$by == $by are grija maska de mai jos
       if($by & INT_HI_MASK)   // Daca factorul depaseste jumate de INT, efectuam 2 inmultiri
       {
          $o = clone $this; // pentru fiecare jumatate de $by trebuie cate un factor
          $this->mul_int(($by >> INT_HALF_BIT_SIZE) & INT_LO_MASK, false);  // Inmultim partea de sus a $by cu $this
          $this->data = str_repeat(NULL_CHAR, INT_SIZE >> 1) . $this->data; // deplasam $this in sus cu jumatate de INT
          $o->mul_int($by & INT_LO_MASK, false);                            // Inmultim partea de jos a $by cu $this
          $this->add_obj($o);                                               // adaugam produsul pentru jumatatea de jos
          unset($dt); 
       }
       else
       {
          $o  = 0;
          $l  = strlen($this->data);
          $dt = &$this->data;
          for($i=0; $i<$l; $i++, $o >>= 8) {
             $o = ord($dt[$i]) * $by + $o;
             $dt[$i] = chr($o & BYTE_MASK);
          }
          for(; $o; $o >>= 8) $dt .= chr($o & BYTE_MASK);
          $dt .= NULL_CHAR; // Numarul trebuie sa fie pozitiv
       }
       if($s) $this->negative();
       return $this->get_val();
    } // mul_int
    
    /*------------------------------------------------------------------------*/
    function mul_obj($op)
    {
       $a  = &$op->data;   // se presupune ca $op este mai scurt decat $this
       $b  = &$this->data;
       $al = strlen($a);
       $bl = strlen($b);
       $s = ord($a[$al-1]) & BYTE_SIGN;
       $m = ord($b[$bl-1]) & BYTE_SIGN;
       if($s) {
          $r = $a;         // backup $op
          $op->negative();
          $op->data = &$r; // restore $op
          if(self::$carry < 0) $al++;
       }   
       if($m) { 
          $this->negative();
          $s ^= $m; // result sign
       }
       if(self::$carry < 0) $bl++;
       if($bl < $al) { // $b trebuie sa fie numarul mai lung 
         $r = &$a; $a  = &$b; $b  = &$r;
         $o = $al; $al = $bl; $bl = $o;
       }
       unset($r); 
       
       $o = 0;
       $r = ''; // rezultatul inmultirii
       $l = $al + $bl - 1;
       global $mxln;
       for($k=0; $k<$l; $k++)
       {
           $m = min($k+1, $al);
           $sum = 0;
           for($i=max(0, $k+1-$bl); $i<$m; $i++)
           {
              $sum++;
      $j = $k-$i;
              $o += ord($a[$i]) * ord($b[$j]); // length($o) <= (2*$al) bytes
           }
           if($sum > $mxln) $mxln = $sum;
           $r .= chr($o & BYTE_MASK);
           $o >>= 8;
       }
       while($o) {  // transportul prelungeste numarul
          $r .= chr($o & BYTE_MASK);
          $o >>= 8;
       }
       
       $this->data = &$r;
       if($s) $this->negative();
       self::$carry = $o;
       return $this->get_val();
    } // mul_obj
    /*------------------------------------------------------------------------*/
    public function set_val($val)
    {
       $this->data = '';
       if(is_int($val) || is_bool($val)) return $this->set_int((int)$val); // datele constituie un singur INT
       if(is_float($val))  $this->set_float($val); else
       if(is_array($val))  parent::set_ints($val); else // un array de numere intregi pentru un numar lung
       if($val instanceof parent) return $this->set_obj($val);
       else
       {
          $radix = func_num_args() > 1 ? func_get_arg(1) : $this->radix;
          $this->set_str($val, $radix);
       }
       return $this->get_val();     
    } 
    
    protected function get_val()
    { 
       $this->reduce();
       return $this->reduce() <= PHP_INT_SIZE ? $this->get_int_s() : $this; 
    }   
    /*------------------------------------------------------------------------*/
    public function add($op)
    {
       if(is_int($op) || is_bool($op)) return $this->add_int((int)$op);
       if(is_float($op)) return $this->add_float($op);
       if(is_array($op)) { 
          $radix = func_num_args() > 1 ? func_get_arg(1) : 0;
          foreach($op as &$v) $this->add($v, $radix); 
          return $this->get_val(); 
       }
       if( !($op instanceof self) ) {
      $o = new self();
          $o->set_str($op, func_num_args() > 1 ? $radix=func_get_arg(1) : 0);
          $op = $o;
       } 
       return $this->add_obj($op);
    }
    /*------------------------------------------------------------------------*/
    public function mul($op)
    {
       if(is_int($op) || is_bool($op)) return $this->mul_int((int)$op);
       if(is_float($op)) return $this->mul_float($op);
       if(is_array($op)) { 
          $radix = func_num_args() > 1 ? func_get_arg(1) : 0;
          foreach($op as &$v) $this->mul($v, $radix); 
          return $this->get_val(); 
       }
       if( !($op instanceof self) ) {
      $o = new self();
          $o->set_str($op, func_num_args() > 1 ? $radix=func_get_arg(1) : 0);
          $op = $o;
       } 
       return $this->mul_obj($op);
    }
    /*------------------------------------------------------------------------*/
    /*!
     * Obtine opusul numarului
     *     
     * Numerele intregi se reprezinta ca complementi fata de 2^n, 
     * de aceea pentru a obtine valoarea negativa a numarului z, 
     * putem aplica formula:
     *       -z == ~z + 1,
     * unde ~z este complementul fata de 2^n a numarului z.
     *       ~z = 2^n - 1 - z
     *      
     * Observatie: ~z - 1 = ~(z + 1)                              
     */
    function negative()
    {
       $dt = &$this->data;
       $l  = strlen($dt);
       for($i=0; $i<$l && $dt[$i] == NULL_CHAR; $i++) ; // cat timp exista transport si nu s-a ajuns la sfarsit
       if($i < $l) 
       {
          self::$carry = 0; // nu exista transport
          $dt[$i] = chr(BYTE_MASK & ~ord($dt[$i]) + 1);
          $i++;
          if($i == $l && ord($dt[$i-1]) == BYTE_SIGN) // cazul special, cand -n == n !
          {
            $dt .= NULL_CHAR;     // numarul a fost negativ si trebuie sa devina pozitiv
            self::$carry = -1; // pentru cazul de exceptie!
          } else
          for(; $i<$l; $i++) $dt[$i] = chr(BYTE_MASK & ~ord($dt[$i])); // cat timp nu s-a ajuns la sfarsit
       }
       else self::$carry = 1; // exista transport (doar pentru valoarea 0)
       return $this;
    }
    /*------------------------------------------------------------------------*/
    /*!
     * Reduce octetii superiori, daca e posibil, fara a skimba valoarea numarului.
     * @return: Nr de octeti ramasi     
     */     
    protected function reduce() // sign
    {
       $l = $this->get_size();
       if(!$l) return 0;
       $g = $this->get_byte($l-1);
       if($g === 0 || $g === BYTE_MASK) // "cifra" superioara e 0 sau ~0
       {
         $l = $this->ltrim_byte($g);
         if(!$l) // s-au redus toti octetii
         {
           $this->push_byte($g); // adaugam octetul purtator de semn
           $l = 1;               // a ramas un singur octet
         }
         else
         {
           $v = $this->get_byte($l-1); // ultimul octet ramas
           if( BYTE_SIGN & ($v ^ $g) ) {
              $this->push_byte($g); // ultima "cifra" trebuie sa pastreze semnul 
              $l++; 
           }
         } 
       }
       return $l; 
    }
    /// Nr de octeti nenuli din numar -1
    function grad()
    {
       return $this->not_null_r();
    }
    /*------------------------------------------------------------------------*/
    protected function set_float($op)
    { 
      /* Reprezentarea pe float difera calitativ, de aceea vom 
       * folosi metode numerice (nu reprezentarea numarului) 
       * de convertire a valorii in formatul intern LongNum. 
       * float == double (mantisa are 52 bitsi)       */
       
       if(PHP_INT_SIZE == 8) return $this->set_int($op); // in acest caz INT il poare contine pe float
       
       // semnul numarului se prelucreaza separat
       if($op<0) {$op = -$op; $s = -1; }
       else $s = 0;
       
       $d   = INT_LO_MASK + 1;   // sqrt(MAX_INT) - jumate din capacitatea INT (ex. pe 32 biti - 0x00010000)
       $isz = PHP_INT_SIZE >> 1; // nr de octeti necesari pentru jumate de INT
       while($op) 
       {
          $f  = floor($op / $d);                      // jumate de INT (binar)
          $this->data .= int2bs($op - $f * $d, $isz); // restul impartirii
          $op = floor($f / $d);                       // a doua jumate de INT
          $this->data .= int2bs($f - $op * $d, $isz); // al doilea rest al impartirii
       }
       if($s) $this->negative();
       return $this->get_val();
    }
    protected function set_obj($op)
    {
        if($op instanceof parent)   // daca obiectul atribuit este de acelasi tip,
           $this->data = $op->data; // pur si simplu se copie datele
        else                        // in caz contrar
           $this->set_str($op);     // se incearca atribuirea valorii STRING a $op 
        return $this->get_val();
    }
    protected function get_obj() { return clone $this; }
    
    /// Un simplu alias pentru set_int($op, 0)
    protected function set_integer($op)
    {
       return $this->set_int($op);
    }
     
    protected function get_integer()
    {
       return $this->get_int_s();
    }
    /*------------------------------------------------------------------------*/
    protected function add_float(&$op)
    { // float == double (mantisa are 52 bitsi)
       if(PHP_INT_SIZE == 8) return $this->add_int($op); // in acest caz INT il poare contine pe float
       return $this->add_obj(new self($op));
    }
    protected function add_int($op)
    {
       $o = new self();
       $o->set_int($op);
       return $this->add_obj($o);
    }
    protected function add_obj($op)
    {
       $al = strlen($this->data);
       $bl = strlen($op->data);
       if($al < $bl) { // $a trebuie sa fie numarul mai lung 
         $a = &$op->data;
         $b = &$this->data;
         $r = $al; $al = $bl; $bl = $r;
       } else {        // $a este numarul cel mai lung
         $a = &$this->data;
         $b = &$op->data;
       }
       $r = '';
       $carry = &self::$carry;
       $carry = 0; // transportul initial lipseste
       
       for($i=0; $i<$bl; $i++) // parcurgem partea din lungimea comuna a ambelor numere
       {
          $carry += ord($a[$i]) + ord($b[$i]); // adunarea "cifrelor" curente + transportul
          $rb = BYTE_MASK & $carry;            // ultima "cifra" din suma curenta 
          $r .= chr($rb);                      // scrie "cifra" in rezultat
          $carry >>= 8;                        // obtinem transportul
       } 
       
       $gb = (ord($b[$bl-1]) & BYTE_SIGN) >> 7; // bitul de semn se plaseaza pe prima pozitie
       for(; $i<$al && ($gb ^ $carry); $i++) // $gb este bitul de semn (0 sau 1), iar $carry poate fi 0 sau 1
       {
          $carry += ord($a[$i]) + $gb;         // $gb reprezinta "cifrele" lui $b de dupa $bl
          $rb = BYTE_MASK & $carry;            // ultima "cifra" din suma curenta
          $r .= chr($rb);                      // scrie "cifra" in rezultat
          $carry >>= 8;                        // obtinem transportul (max 1)
       }
       /* Cand apare depasirea capacitatii curente a numerelor?
        * 1. $a > 0 && $b > 0 && $r < 0, no carry
        * 2. $a < 0 && $b < 0 && $r > 0, carry   
        * 
        * Nota: Daca $a si $b au semne diferite, depasirea nu poate avea loc!                    
        */ 
       
       if($i<$al) // $ga == $gr
       {
          $r .= substr($a, $i, $al-$i);
       }
       else
       {
          $gr = ($rb & BYTE_SIGN) ? BYTE_MASK : 0;
          if($gr != $gb)
          {
            $ga = ord($a[$al-1]) & BYTE_SIGN ? BYTE_MASK : 0;
            if($ga == $gb) $r .= chr($ga);
          }
       }
       
       $this->data = &$r;
       return $this->get_val();
       
       // Cream obiectul numarului din $r
       $ro = new self();
       $ro->data = &$r;
       return $ro;
       return $ro->get_val();
    } // add_obj
    
    /*------------------------------------------------------------------------*/
    /// Obtine semnul numarului: !0 pentru negativ si 0 pentru pozitiv
    protected function get_sign()
    {
       $l = parent::get_size();
       $b = parent::get_byte($l-1);
       return ($b & BYTE_SIGN); 
    } 
   
    /// Seteaza semnul numarului: TRUE <-> -1; FALSE <-> 0;
    protected function set_sign($sgn)
    {
       if(!is_numeric($sng)) $sng = $sng     ? BYTE_SIGN : 0;
       else                  $sng = $sgn < 0 ? BYTE_SIGN : 0;
       $osgn = $this->get_sign();
       if($sgn ^ $osgn)      // daca semnul cerut difera ce cel al numarului
          $this->negative(); // se obtine opusul numarului curent
       return $sgn;
    } 
    /*------------------------------------------------------------------------*/
    /// Verifica daca numarul este o putere a lui 2 (2^n).
    function is_pow2()
    {
      if($l = strlen($this->data)) 
      {
         $dt = &$this->data;
         while($l--) if($dt[$l] != NULL_CHAR) 
         {
            $i = ord($dt[$l]);
            if($i & ($i - 1)) return false;
            $i = $l;
            while($l--) if($dt[$l] != NULL_CHAR) return false;
            return $i+1; // pozitia octetului nenul
         }
      }
      return true; 
    }
// /*------------------------------------------------------------------------*/
//     function negative_i()
//     {
//        $o  = &self::$carry;
//        $v  = $this->reset;
//        $o  = 1;
//        if(!$v)  // ~0 + 1 = 2^n-0 + 1 => exista transport
//        { 
//          while($o && $v!==false) // cat timp exista transport si nu s-a ajuns la sfarsit
//          {
//             $v = ~$v;
//             // LO of $v
//             $o  += INT_LO_MASK & $v; 
//             $f   = INT_LO_MASK & $o;
//             $o >>= INT_HALF_BIT_SIZE;
//             
//             // HI of $v
//             $o  += INT_LO_MASK & ($v >> INT_HALF_BIT_SIZE);
//             $g   = INT_LO_MASK & $o;
//             $o >>= INT_HALF_BIT_SIZE;
//              
//             $this->current = ($g << INT_HALF_BIT_SIZE) | $f;
//             $v = $this->next;
//          }
//        } else { $v -= $o; $o = 0; }      
//        while($v!==false) // cat timp nu s-a ajuns la sfarsit
//        {
//           $this->current = ~$v;
//           $v = $this->next;
//        }
//        return $this;
//     }
// /*------------------------------------------------------------------------*/
//     protected function add_int_i($op)
//     {
//        self::$carry = 0; // transportul initial lipseste
//        $v = $this->reset;
//        $this->current = add_carry($v, $op, self::$carry);
//        $g = ($op & INT_SIGN) >> INT_BIT_SIZE-1;
//        $v = $this->next;       
//        while($v !== false && ((self::$carry ^ $g) & 1)) 
//        {
//           $this->current = add_carry($v, $g, self::$carry);  
//           $v = $this->next;       
//        }
//        unset($this->cursor);
//        return $this->get_val();
//     }
// /*------------------------------------------------------------------------*/
//     function add_obj_i($op)
//     {
//        if($this->size > $op->size) {
//           $ho = $this;
//           $lo = $op;
//        }
//        else {
//           $lo = $this;
//           $ho = $op;
//        }
//        
//        self::$carry = 0; // transportul initial lipseste
//        $lv = $lo->reset;
//        $hv = $ho->reset;
//        while($lv !== false) // partea din lungimea comuna a ambelor numere
//        {
//           $this->current = add_carry($hv, $lv, self::$carry);
//           $lv = $lo->next;
//           $hv = $ho->next;
//        } 
//        $g = $lo->sign;
//        while($hv !== false && (self::$carry ^ $g & 1)) 
//        {
//           $this->set_int(add_carry($hv, $g, self::$carry), $ho->cursor);  
//           $hv = $ho->next;       
//        }
//        if($hv !== false && $ho != $this)
//        {
//           $l = $ho->len;
//           do $this->append_bin($ho->get_bin($ho->cursor++)); 
//           while($ho->cursor < $l);
//        }
//        return $this->get_val();
//     }
// /*------------------------------------------------------------------------*/
//     public function div_int_i($by)
//     {
//        if($by == 0) { return self::$carry = -1; } 
//        self::$carry = 0;
//        if($by == 1) return $this;
//        $o  = &self::$carry;
//        $v  = $this->end;
//        while($v !== false)
//        {
//           // HI of $v
//           $w = ($o << INT_HALF_BIT_SIZE) | INT_LO_MASK & ($v >> INT_HALF_BIT_SIZE);
//           $o  = $w % $by;
//           $f = (int)(($w-$o) / $by); // Scadem restul pentru a obtine int la impartire
//           
//           // LO of $v
//           $w = ($o << INT_HALF_BIT_SIZE) | INT_LO_MASK & $v; 
//           $o  = $w % $by;
//           $g = (int)(($w-$o) / $by); // Scadem restul pentru a obtine int la impartire
//           
//           $this->current = ($f << INT_HALF_BIT_SIZE) | $g; 
//           $v = $this->prev;
//        }
//        return $this->get_val();
//     } // div_int_i    
// /*------------------------------------------------------------------------*/
};
/*------------------------------------------------------------------------------------------*/
function ln_str($val, $radix=false)
{
   if( ! $val instanceof LongNum ) $val = new LongNum($val);
   return $val->get_str($radix); 
}
function ln_add($op1, $op2)
{
   $r = new LongNum($op1);
   return $r->add($op2);
}
function ln_sub($op1, $op2)
{
   $r = new LongNum($op2);
   $r->negative();
   return $r->add($op1);
}
function ln_mul($op1, $op2)
{
   $r = new LongNum($op1);
   return $r->mul($op2);
}
/*------------------------------------------------------------------------------------------*/
?>

Aici acumulez programe şi algoritmi interesanti alcătuiţi de mine (cu mici excepţii) pe parcursul studierii unor limbaje de programare.

Cea mai mare parte din ele sunt realizate în Pascal. 

Nu am scopul creării unui curs specializat sau a descrierii detaliate a anumitor limbaje, ci doar prezint informaţii utile, plus ceva exemple interesante...

 

Răsfoitorul de fișiere (File Browser):

Codul sursă al programelor este organizat în mape şi fişiere.

Paginile care conțin cod sursă de programe de regulă au un răsfoitor de fișiere în partea stangă a paginii reprezentat de un bloc cu titlul „File Browser”.

Pentru a vizualiza un program sau conţinutul unei mape, faceţi click pe numele fişierului / mapei. Dacă fişierul nu este textual, el se va descărca automat, iar dacă este textual, conținutul lui se va afișa într-un bloc pe centrul paginii.

Pentru a descărca un fişier, faceţi click pe dimensiunea (size) lui.

arr_d Limba / Language


 


arr_r Login
 
 
Loading...