Math
[ class tree: Math ] [ index: Math ] [ all elements ]

Source for file BinaryUtils.php

Documentation is available at BinaryUtils.php

  1. <?php
  2.  
  3. // {{{ license
  4.  
  5. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  6. //
  7. // +----------------------------------------------------------------------+
  8. // | PHP Version 4                                                        |
  9. // +----------------------------------------------------------------------+
  10. // | Copyright (c) 1997-2002 The PHP Group                                |
  11. // +----------------------------------------------------------------------+
  12. // | This source file is subject to version 2.0 of the PHP license,       |
  13. // | that is bundled with this package in the file LICENSE, and is        |
  14. // | available at through the world-wide-web at                           |
  15. // | http://www.php.net/license/2_02.txt.                                 |
  16. // | If you did not receive a copy of the PHP license and are unable to   |
  17. // | obtain it through the world-wide-web, please send a note to          |
  18. // | license@php.net so we can mail you a copy immediately.               |
  19. // +----------------------------------------------------------------------+
  20. // | Authors: Markus Nix <mnix@docuverse.de>                              |
  21. // +----------------------------------------------------------------------+
  22. //
  23.  
  24. // }}}
  25.  
  26.  
  27. // {{{ defines
  28. define('MATH_BINARYUTILS_BIG_ENDIAN',    0x0000);
  29. define('MATH_BINARYUTILS_LITTLE_ENDIAN'0x0001);
  30. // }}}
  31.  
  32.  
  33. /**
  34.  * Class with static helpers for easy handling of bit and byte stuff.
  35.  *
  36.  * @author  Markus Nix <mnix@docuverse.de>
  37.  * @access  public
  38.  * @package Math
  39.  * @version $Id: BinaryUtils.php,v 1.2 2004/09/08 11:56:11 docuverse_de Exp $
  40.  * @static
  41.  */
  42.  
  43. {
  44.     // {{{ add
  45.     /**
  46.      * Binary add.
  47.      *
  48.      * @param  int    $num1 
  49.      * @param  int    $num2 
  50.      * @access public
  51.      * @static
  52.      */
  53.     function add($num1$num2)
  54.     {
  55.         $carry $num1 $num2;
  56.  
  57.         do {
  58.             $carry $carry << 1;
  59.             $num1  $num1 $num2;
  60.             $sum   $num1 $carry;
  61.             $num2  $carry;
  62.             $carry $num1 $num2;
  63.         while ($carry != 0);
  64.  
  65.         return $sum;
  66.     }
  67.     // }}}
  68.  
  69.     // {{{ subtract
  70.     /**
  71.      * Binary subtract.
  72.      *
  73.      * @param  int    $num1 
  74.      * @param  int    $num2 
  75.      * @access public
  76.      * @static
  77.      */
  78.     function subtract($num1$num2)
  79.     {
  80.         // compute two's compliment
  81.         $num2 =~ $num2;
  82.         $num2 =  Math_BinaryUtils::add($num21);
  83.         $diff =  Math_BinaryUtils::add($num1$num2);
  84.  
  85.         return $diff;
  86.     }
  87.     // }}}
  88.  
  89.     // {{{ binToDec
  90.     /**
  91.      * Bin to dec conversion.
  92.      *
  93.      * @param  string  $binstring 
  94.      * @return int 
  95.      * @access public
  96.      * @static
  97.      */
  98.     function binToDec($binstring)
  99.     {
  100.         $decvalue = 0;
  101.  
  102.         for ($i = 0; $i strlen($binstring)$i++{
  103.             $decvalue += ((int)substr($binstringstrlen($binstring$i - 11)) pow(2$i);
  104.         }
  105.  
  106.         return Math_BinaryUtils::_castAsInt($decvalue);
  107.     }
  108.     // }}}
  109.  
  110.     // {{{ decToBin
  111.     /**
  112.      * Dec to bin conversion.
  113.      *
  114.      * @param  int    $number 
  115.      * @access public
  116.      * @static
  117.      */
  118.     function decToBin($number)
  119.     {
  120.         while $number >= 256 {
  121.             $bytes[(($number / 256(floor($number / 256))) * 256;
  122.             $number  floor($number / 256);
  123.         }
  124.  
  125.         $bytes[]   $number;
  126.         $binstring '';
  127.  
  128.         for ($i = 0; $i count$bytes )$i++{
  129.             $binstring (($i == count($bytes- 1)decbin($bytes["$i"]str_pad(decbin($bytes["$i"])8'0'STR_PAD_LEFT)) $binstring;
  130.         }
  131.  
  132.         return $binstring;
  133.     }
  134.     // }}}
  135.  
  136.     // {{{ floatToBin
  137.     /**
  138.      * Converts a single-precision floating point number
  139.      * to a 6 byte binary string.
  140.      *
  141.      * @param  float  $num  the float to convert
  142.      * @return string       the binary string representing the float
  143.      * @access public
  144.      * @static
  145.      */
  146.     function floatToBin($num)
  147.     {
  148.         // Save the sign bit.
  149.         $sign ($num < 0)? 0x8000 : 0x0000;
  150.  
  151.         // Now treat the number as positive...
  152.         if ($num < 0)
  153.             $num = -$num;
  154.  
  155.         // Get the exponent and limit to 15 bits.
  156.         $exponent (1 + (int)floor(log10($num))) 0x7FFF;
  157.  
  158.         // Convert the number into a fraction.
  159.         $num /= pow(10$exponent);
  160.  
  161.         // Now convert the fraction to a 31bit int.
  162.         // We don't use the full 32bits, because the -ve numbers
  163.         // stuff us up -- this results in better than single
  164.         // precision floats, but not as good as double precision.
  165.         $fraction = (int)floor($num * 0x7FFFFFFF);
  166.  
  167.         // Pack the number into a 6 byte binary string
  168.         return Math_BinaryUtils::_decToBin_bytes($sign $exponent2Math_BinaryUtils::_decToBin_bytes($fraction4);
  169.     }
  170.     // }}}
  171.  
  172.     // {{{ binToFloat
  173.     /**
  174.      * Converts a 6 byte binary string to a single-precision
  175.      * floating point number.
  176.      *
  177.      * @param  string  $data  the binary string to convert
  178.      * @return the floating point number
  179.      * @access public
  180.      * @static
  181.      */
  182.     function binToFloat(&$data)
  183.     {
  184.         // Extract the sign bit and exponent.
  185.         $exponent  Math_BinaryUtils::_binToDec_length(substr($data02)2);
  186.         $sign      (($exponent 0x8000== 0)? 1 : -1;
  187.         $exponent &= 0x7FFF;
  188.  
  189.         // Extract the fractional part.
  190.         $fraction Math_BinaryUtils::_binToDec_length(substr($data24)4);
  191.  
  192.         // Return the reconstructed float.
  193.         return $sign pow(10$exponent$fraction / 0x7FFFFFFF;
  194.     }
  195.     // }}}
  196.  
  197.     // {{{ binToString
  198.     /**
  199.      * Bin to string conversion. For example,
  200.      * return 'hi' for input of '0110100001101001'.
  201.      *
  202.      * @param  string  $binstring 
  203.      * @return string 
  204.      * @access public
  205.      * @static
  206.      */
  207.     function binToString($binstring)
  208.     {
  209.         $string '';
  210.         $binstringreversed strrev($binstring);
  211.  
  212.         for ($i = 0; $i strlen($binstringreversed)$i += 8{
  213.             $string chr(Math_BinaryUtils::binToDec(strrev(substr($binstringreversed$i8)))) $string;
  214.         }
  215.  
  216.         return $string;
  217.     }
  218.     // }}}
  219.  
  220.     // {{{ decbin_pad
  221.     /**
  222.      * Converts Decimal -> Binary, and left-pads it with $padvalue 0's.
  223.      *
  224.      * @param  int    $inputdec 
  225.      * @param  int    $padvalue 
  226.      * @return string 
  227.      * @access public
  228.      * @static
  229.      */
  230.     function decbin_pad($inputdec$padvalue)
  231.     {
  232.         return str_pad(decbin($inputdec)$padvalue"0"STR_PAD_LEFT);
  233.     }
  234.     // }}}
  235.  
  236.     // {{{ binToDec_fraction
  237.     /**
  238.      * Bin to dec conversion with fractions.
  239.      *
  240.      * @return int 
  241.      * @access public
  242.      * @static
  243.      */
  244.     function binToDec_fraction($inputfraction)
  245.     {
  246.         $binRep Math_BinaryUtils::decbin_pad($inputfraction8);
  247.         $old    = 0;
  248.  
  249.         for ($i = 8; $i--; $i > 0{
  250.             $old ($old $binRep[$i]/ 2;
  251.         }
  252.  
  253.         return $old;
  254.     }
  255.     // }}}
  256.  
  257.     // {{{ getNativeOrder
  258.     /**
  259.      * Retrieve native byte order of this OS.
  260.      * Little Endian: Intel's 80x86 processors and their clones,
  261.      * Big Endian: SPARC, Motorola's 68K, and the PowerPC families.
  262.      *
  263.      * @access  public
  264.      * @return  int 
  265.      * @static
  266.      */
  267.     function getNativeOrder()
  268.     {
  269.         switch (pack('d'1)) {
  270.         case "\77\360\0\0\0\0\0\0":
  271.             return MATH_BINARYUTILS_BIG_ENDIAN;
  272.  
  273.         case "\0\0\0\0\0\0\360\77":
  274.             return MATH_BINARYUTILS_LITTLE_ENDIAN;
  275.         }
  276.     }
  277.     // }}}
  278.  
  279.     // {{{ littleEndianToString
  280.     /**
  281.      * Little Endian to String conversion.
  282.      *
  283.      * @param  int    $number 
  284.      * @param  int    $minbytes 
  285.      * @param  bool   $synchsafe 
  286.      * @return string 
  287.      * @access public
  288.      * @static
  289.      */
  290.     function littleEndianToString($number$minbytes = 1$synchsafe = false)
  291.     {
  292.         while ($number > 0{
  293.             if ($synchsafe{
  294.                 $intstring $intstring chr($number 127);
  295.                 $number >>= 7;
  296.             else {
  297.                 $intstring $intstring chr($number 255);
  298.                 $number >>= 8;
  299.             }
  300.         }
  301.  
  302.         return $intstring;
  303.     }
  304.     // }}}
  305.  
  306.     // {{{ bigEndianToString
  307.     /**
  308.      * Big Endian to String conversion.
  309.      *
  310.      * @param  int    $number 
  311.      * @param  int    $minbytes 
  312.      * @param  bool   $synchsafe 
  313.      * @param  bool   $signed 
  314.      * @return string 
  315.      * @access public
  316.      * @static
  317.      */
  318.     function bigEndianToString($number$minbytes = 1$synchsafe = false$signed = false)
  319.     {
  320.         if $number < 0 {
  321.             return false;
  322.         }
  323.  
  324.         $maskbyte  (($synchsafe || $signed)? 0x7F : 0xFF);
  325.         $intstring '';
  326.  
  327.         if ($signed{
  328.             if $minbytes > 4 {
  329.                 return false;
  330.             }
  331.  
  332.             $number $number (0x80 << (8 * ($minbytes - 1)));
  333.         }
  334.  
  335.         while ($number != 0{
  336.             $quotient  ($number ($maskbyte + 1));
  337.             $intstring chr(ceil( ($quotient floor($quotient)) $maskbyte)) $intstring;
  338.             $number    floor($quotient);
  339.         }
  340.  
  341.         return str_pad($intstring$minbyteschr(0)STR_PAD_LEFT);
  342.     }
  343.     // }}}
  344.  
  345.     // {{{ performPack
  346.     /**
  347.      * Perform pack.
  348.      *
  349.      * @param  int    $val 
  350.      * @param  int    $bytes 
  351.      * @return string 
  352.      * @access public
  353.      * @static
  354.      */
  355.     function performPack($val$bytes = 2)
  356.     {
  357.         for ($ret ''$i = 0; $i $bytes$i++$val floor($val / 256)) {
  358.             $ret .= chr($val % 256);
  359.         }
  360.  
  361.         return $ret;
  362.     }
  363.     // }}}
  364.  
  365.     // {{{ performUnpack
  366.     /**
  367.      * Perform unpack.
  368.      *
  369.      * @param  string $val 
  370.      * @return int 
  371.      * @access public
  372.      * @static
  373.      */
  374.     function performUnpack($val)
  375.     {
  376.         for ($len strlen($val)$ret = 0$i = 0; $i $len$i++{
  377.             $ret += (int)ord(substr($val$i1)) pow(28 * $i);
  378.         }
  379.  
  380.         return $ret;
  381.     }
  382.     // }}}
  383.  
  384.     // {{{ bytestringToGUID
  385.     /**
  386.      * Transform bytestring to GUID.
  387.      *
  388.      * @param  string $byte_str 
  389.      * @return string GUID string
  390.      * @access public
  391.      * @static
  392.      */
  393.     function bytestringToGUID($byte_str)
  394.     {
  395.         $guid_str  strtoupper(str_pad(dechex(ord($byte_str{3))2'0'STR_PAD_LEFT));
  396.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{2))2'0'STR_PAD_LEFT));
  397.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{1))2'0'STR_PAD_LEFT));
  398.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{0))2'0'STR_PAD_LEFT));
  399.         $guid_str .= '-';
  400.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{5))2'0'STR_PAD_LEFT));
  401.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{4))2'0'STR_PAD_LEFT));
  402.         $guid_str .= '-';
  403.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{7))2'0'STR_PAD_LEFT));
  404.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{6))2'0'STR_PAD_LEFT));
  405.         $guid_str .= '-';
  406.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{8))2'0'STR_PAD_LEFT));
  407.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{9))2'0'STR_PAD_LEFT));
  408.         $guid_str .= '-';
  409.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{10}))2'0'STR_PAD_LEFT));
  410.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{11}))2'0'STR_PAD_LEFT));
  411.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{12}))2'0'STR_PAD_LEFT));
  412.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{13}))2'0'STR_PAD_LEFT));
  413.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{14}))2'0'STR_PAD_LEFT));
  414.         $guid_str .= strtoupper(str_pad(dechex(ord($byte_str{15}))2'0'STR_PAD_LEFT));
  415.  
  416.         return $guid_str;
  417.     }
  418.     // }}}
  419.  
  420.     // {{{ GUIDToBytestring
  421.     /**
  422.      * Transform GUID to bytestring.
  423.      *
  424.      * @param  string $guid_str 
  425.      * @return string byte string
  426.      * @access public
  427.      * @static
  428.      */
  429.     function GUIDToBytestring($guid_str)
  430.     {
  431.         // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way:
  432.         // first 4 bytes are in little-endian order
  433.         // next 2 bytes are appended in little-endian order
  434.         // next 2 bytes are appended in little-endian order
  435.         // next 2 bytes are appended in big-endian order
  436.         // next 6 bytes are appended in big-endian order
  437.  
  438.         // AaBbCcDd-EeFf-GgHh-IiJj-KkLlMmNnOoPp is stored as this 16-byte string:
  439.         // $Dd $Cc $Bb $Aa $Ff $Ee $Hh $Gg $Ii $Jj $Kk $Ll $Mm $Nn $Oo $Pp
  440.  
  441.         $hexbytechar_str  chr(hexdec(substr($guid_str,  62)));
  442.         $hexbytechar_str .= chr(hexdec(substr($guid_str,  42)));
  443.         $hexbytechar_str .= chr(hexdec(substr($guid_str,  22)));
  444.         $hexbytechar_str .= chr(hexdec(substr($guid_str,  02)));
  445.         $hexbytechar_str .= chr(hexdec(substr($guid_str112)));
  446.         $hexbytechar_str .= chr(hexdec(substr($guid_str,  92)));
  447.         $hexbytechar_str .= chr(hexdec(substr($guid_str162)));
  448.         $hexbytechar_str .= chr(hexdec(substr($guid_str142)));
  449.         $hexbytechar_str .= chr(hexdec(substr($guid_str192)));
  450.         $hexbytechar_str .= chr(hexdec(substr($guid_str212)));
  451.         $hexbytechar_str .= chr(hexdec(substr($guid_str242)));
  452.         $hexbytechar_str .= chr(hexdec(substr($guid_str262)));
  453.         $hexbytechar_str .= chr(hexdec(substr($guid_str282)));
  454.         $hexbytechar_str .= chr(hexdec(substr($guid_str302)));
  455.         $hexbytechar_str .= chr(hexdec(substr($guid_str322)));
  456.         $hexbytechar_str .= chr(hexdec(substr($guid_str342)));
  457.  
  458.         return $hexbytechar_str;
  459.     }
  460.     // }}}
  461.  
  462.     // {{{ littleEndianToInt
  463.     /**
  464.      * Little Endian to int conversion.
  465.      *
  466.      * @param  string $byteword 
  467.      * @param  bool   $signed 
  468.      * @return int 
  469.      * @access public
  470.      * @static
  471.      */
  472.     function littleEndianToInt($byteword$signed = false)
  473.     {
  474.         return Math_BinaryUtils::bigEndianToInt(strrev($byteword)false$signed);
  475.     }
  476.     // }}}
  477.  
  478.     // {{{ bigEndianToInt
  479.     /**
  480.      * Big Endian to int conversion.
  481.      *
  482.      * @param  string $byteword 
  483.      * @param  bool   $synchsafe 
  484.      * @param  bool   $signed 
  485.      * @return int 
  486.      * @access public
  487.      * @static
  488.      */
  489.     function bigEndianToInt($byteword$synchsafe = false$signed = false)
  490.     {
  491.         $intvalue = 0;
  492.         $bytewordlen strlen($byteword);
  493.  
  494.         for ($i = 0; $i $bytewordlen$i++{
  495.             // disregard MSB, effectively 7-bit bytes
  496.             if ($synchsafe{
  497.                 $intvalue $intvalue (ord($byteword{$i}0x7F<< (($bytewordlen - 1 - $i* 7);
  498.             else {
  499.                 $intvalue += ord($byteword{$i}pow(256($bytewordlen - 1 - $i));
  500.             }
  501.         }
  502.  
  503.         if ($signed && !$synchsafe{
  504.             // synchsafe ints are not allowed to be signed
  505.             switch ($bytewordlen{
  506.             case 1:
  507.  
  508.             case 2:
  509.  
  510.             case 3:
  511.  
  512.             case 4:
  513.                 $signmaskbit = 0x80 << (8 * ($bytewordlen - 1));
  514.  
  515.                 if ($intvalue $signmaskbit{
  516.                     $intvalue = 0 - ($intvalue ($signmaskbit - 1));
  517.                 }
  518.  
  519.                 break;
  520.  
  521.             default:
  522.                 break;
  523.             }
  524.         }
  525.  
  526.         return Math_BinaryUtils::_castAsInt($intvalue);
  527.     }
  528.     // }}}
  529.  
  530.     // {{{ littleEndianToBin
  531.     /**
  532.      * Little Endian to bin conversion.
  533.      *
  534.      * @param  string $byteword 
  535.      * @return string 
  536.      * @access public
  537.      * @static
  538.      * @note   untested
  539.      */
  540.     function littleEndianToBin($byteword)
  541.     {
  542.         return Math_BinaryUtils::bigEndianToBin(strrev($byteword));
  543.     }
  544.     // }}}
  545.  
  546.     // {{{ bigEndianToBin
  547.     /**
  548.      * Big Endian to bin conversion.
  549.      *
  550.      * @param  string $byteword 
  551.      * @return string 
  552.      * @access public
  553.      * @static
  554.      */
  555.     function bigEndianToBin($byteword)
  556.     {
  557.         $binvalue    '';
  558.         $bytewordlen strlen($byteword);
  559.  
  560.         for ($i = 0; $i $bytewordlen$i++{
  561.             $binvalue .= str_pad(decbin(ord($byteword{$i}))8'0'STR_PAD_LEFT);
  562.         }
  563.  
  564.         return $binvalue;
  565.     }
  566.     // }}}
  567.  
  568.     // {{{ littleEndianToFloat
  569.     /**
  570.      * Little Endian to float conversion.
  571.      *
  572.      * @param  string $byteword 
  573.      * @return mixed  Either float or false on error
  574.      * @access public
  575.      * @static
  576.      */
  577.     function littleEndianToFloat($byteword)
  578.     {
  579.         return Math_BinaryUtils::bigEndianToFloat(strrev($byteword));
  580.     }
  581.     // }}}
  582.  
  583.     // {{{ bigEndianToFloat
  584.     /**
  585.      * Big Endian to float conversion.
  586.      *
  587.      * @param  string $byteword 
  588.      * @return mixed  Either float or false on error
  589.      * @access public
  590.      * @static
  591.      */
  592.     function bigEndianToFloat($byteword)
  593.     {
  594.         // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
  595.         // http://www.psc.edu/general/software/packages/ieee/ieee.html
  596.         // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
  597.  
  598.         $bitword Math_BinaryUtils::bigEndianToBin($byteword);
  599.         $signbit $bitword{0};
  600.  
  601.         if (strlen($byteword== 4// 32-bit DWORD
  602.             $exponentbits = 8;
  603.             $fractionbits = 23;
  604.         else if (strlen($byteword== 8// 64-bit QWORD
  605.             $exponentbits = 11;
  606.             $fractionbits = 52;
  607.         else {
  608.             return false;
  609.         }
  610.  
  611.         $exponentstring substr($bitword1$exponentbits);
  612.         $fractionstring substr($bitword9$fractionbits);
  613.  
  614.         $exponent Math_BinaryUtils::binToDec($exponentstring);
  615.         $fraction Math_BinaryUtils::binToDec($fractionstring);
  616.  
  617.         if (($exponent == (pow(2$exponentbits- 1)) && ($fraction != 0)) {
  618.             // Not a number
  619.             $float_val = false;
  620.         else if (($exponent == (pow(2$exponentbits- 1)) && ($fraction == 0)) {
  621.             if ($signbit == '1'{
  622.                 $float_val '-infinity';
  623.             else {
  624.                 $float_val '+infinity';
  625.             }
  626.         else if (($exponent == 0&& ($fraction == 0)) {
  627.             if ($signbit == '1'{
  628.                 $float_val = -0;
  629.             else {
  630.                 $float_val = 0;
  631.             }
  632.  
  633.             $float_val ($signbit? 0 : -0);
  634.         else if (($exponent == 0&& ($fraction != 0)) {
  635.             // These are 'unnormalized' values
  636.             $float_val pow(2(-1 * (pow(2$exponentbits - 1- 2))) Math_BinaryUtils::decimalBinaryToFloat($fractionstring);
  637.  
  638.             if ($signbit == '1'{
  639.                 $float_val *= -1;
  640.             }
  641.         else if ($exponent != 0{
  642.             $float_val pow(2($exponent (pow(2$exponentbits - 1- 1))) (1 + Math_BinaryUtils::decimalBinaryToFloat($fractionstring));
  643.  
  644.             if ($signbit == '1'{
  645.                 $float_val *= -1;
  646.             }
  647.         }
  648.  
  649.         return (float)$float_val;
  650.     }
  651.     // }}}
  652.  
  653.     // {{{ floatToBinaryDecimal
  654.     /**
  655.      * Transform float value to binary decimal.
  656.      *
  657.      * @param  float  $float_val 
  658.      * @access public
  659.      * @static
  660.      */
  661.     function floatToBinaryDecimal($float_val)
  662.     {
  663.         $maxbits        = 128; // to how many bits of precision should the calculations be taken?
  664.         $intpart        Math_BinaryUtils::_truncate($float_val);
  665.         $floatpart      abs($float_val $intpart);
  666.         $pointbitstring '';
  667.  
  668.         while (($floatpart != 0&& (strlen($pointbitstring$maxbits)) {
  669.             $floatpart      *= 2;
  670.             $pointbitstring .= (string)Math_BinaryUtils::_truncate($floatpart);
  671.             $floatpart      -= Math_BinaryUtils::_truncate($floatpart);
  672.         }
  673.  
  674.         $binarypointnumber decbin($intpart'.' $pointbitstring;
  675.         return $binarypointnumber;
  676.     }
  677.     // }}}
  678.  
  679.     // {{{ normalizeBinaryPoint
  680.     /**
  681.      * Normalize binary points.
  682.      *
  683.      * @param  string $binarypointnumber 
  684.      * @param  int    $maxbits 
  685.      * @return array 
  686.      * @access public
  687.      * @static
  688.      */
  689.     function normalizeBinaryPoint($binarypointnumber$maxbits = 52)
  690.     {
  691.         if (strpos($binarypointnumber'.'=== false{
  692.             $binarypointnumber '0.' $binarypointnumber;
  693.         else if ($binarypointnumber{0== '.'{
  694.             $binarypointnumber '0' $binarypointnumber;
  695.         }
  696.  
  697.         $exponent = 0;
  698.  
  699.         while (($binarypointnumber{0!= '1'|| (substr($binarypointnumber11!= '.')) {
  700.             if (substr($binarypointnumber11== '.'{
  701.                 $exponent--;
  702.                 $binarypointnumber substr($binarypointnumber21'.' substr($binarypointnumber3);
  703.             else {
  704.                 $pointpos  strpos($binarypointnumber'.');
  705.                 $exponent += ($pointpos - 1);
  706.  
  707.                 $binarypointnumber str_replace('.'''$binarypointnumber);
  708.                 $binarypointnumber $binarypointnumber{0'.' substr($binarypointnumber1);
  709.             }
  710.         }
  711.  
  712.         $binarypointnumber str_pad(substr($binarypointnumber0$maxbits + 2)$maxbits + 2'0'STR_PAD_RIGHT);
  713.  
  714.         return array(
  715.             'normalized' => $binarypointnumber,
  716.             'exponent'   => (int)$exponent
  717.         );
  718.     }
  719.     // }}}
  720.  
  721.     // {{{ decimalBinaryToFloat
  722.     /**
  723.      * Transform decimal binary to float.
  724.      *
  725.      * @param  string $binarynumerator 
  726.      * @return float 
  727.      * @access public
  728.      * @static
  729.      */
  730.     function decimalBinaryToFloat($binarynumerator)
  731.     {
  732.         $numerator   Math_BinaryUtils::binToDec($binarynumerator);
  733.         $denominator Math_BinaryUtils::binToDec(str_repeat('1'strlen($binarynumerator)));
  734.  
  735.         return ($numerator $denominator);
  736.     }
  737.     // }}}
  738.  
  739.     // {{{ getHexBytes
  740.     /**
  741.      * Get hex bytes.
  742.      *
  743.      * @param  string $string 
  744.      * @return string 
  745.      * @access public
  746.      * @static
  747.      */
  748.     function getHexBytes($string)
  749.     {
  750.         $ret_str '';
  751.  
  752.         for ($i = 0; $i strlen($string)$i++{
  753.             $ret_str .= str_pad(dechex(ord(substr($string$i1)))2'0'STR_PAD_LEFT' ';
  754.         }
  755.  
  756.         return $ret_str;
  757.     }
  758.     // }}}
  759.  
  760.     // {{{ getTextBytes
  761.     /**
  762.      * Get text bytes.
  763.      *
  764.      * @param  string $string 
  765.      * @return string 
  766.      * @access public
  767.      * @static
  768.      */
  769.     function getTextBytes($string)
  770.     {
  771.         $ret_str '';
  772.  
  773.         for ($i = 0; $i strlen($string)$i++ {
  774.             if (ord(substr($string$i1)) <= 31 {
  775.                 $ret_str .= '   ';
  776.             else {
  777.                 $ret_str .= ' ' substr($string$i1' ';
  778.             }
  779.         }
  780.  
  781.         return $ret_str;
  782.     }
  783.     // }}}
  784.  
  785.  
  786.     // private methods
  787.  
  788.     // {{{ _truncate
  789.     /**
  790.      * Tuncates a floating-point number at the decimal point
  791.      * returns int (if possible, otherwise double)
  792.      *
  793.      * @param  float   $float_val 
  794.      * @return int 
  795.      * @access private
  796.      * @static
  797.      */
  798.     function _truncate($float_val)
  799.     {
  800.         if ($float_val >= 1{
  801.             $truncatednumber floor($float_val);
  802.         else if ($float_val <= -1{
  803.             $truncatednumber ceil($float_val);
  804.         else {
  805.             $truncatednumber = 0;
  806.         }
  807.  
  808.         if ($truncatednumber <= pow(230)) {
  809.             $truncatednumber = (int)$truncatednumber;
  810.         }
  811.  
  812.         return $truncatednumber;
  813.     }
  814.     // }}}
  815.  
  816.     // {{{ _castAsInt
  817.     /**
  818.      * Convert a float to type int, only if possible.
  819.      *
  820.      * @param  float   $float_val 
  821.      * @return int 
  822.      * @access private
  823.      * @static
  824.      */
  825.     function _castAsInt($float_val)
  826.     {
  827.         if (Math_BinaryUtils::_truncate($float_val== $float_val{
  828.             // it's not floating point
  829.             if ($float_val <= pow(230)) {
  830.                 // it's within int range
  831.                 $float_val = (int)$float_val;
  832.             }
  833.         }
  834.  
  835.         return $float_val;
  836.     }
  837.     // }}}
  838.  
  839.     // {{{ _decToBin_bytes
  840.     /**
  841.      * Converts an int to a binary string, low byte first.
  842.      *
  843.      * @param  int     $num    number to convert
  844.      * @param  int     $bytes  minimum number of bytes to covert to
  845.      * @return string  the binary string form of the number
  846.      * @access private
  847.      * @static
  848.      */
  849.     function _decToBin_bytes($num$bytes)
  850.     {
  851.         $result "";
  852.  
  853.         for ($i = 0; $i $bytes; ++$i{
  854.             $result .= chr($num 0xFF);
  855.             $num $num >> 8;
  856.         }
  857.  
  858.         return $result;
  859.     }
  860.     // }}}
  861.  
  862.     // {{{ _binToDec_length
  863.     /**
  864.      * Converts a binary string to an int, low byte first.
  865.      *
  866.      * @param  string  $str   binary string to convert
  867.      * @param  int     $len   length of the binary string to convert
  868.      * @return int     the int version of the binary string
  869.      * @access private
  870.      * @static
  871.      */
  872.     function _binToDec_length(&$str$len)
  873.     {
  874.         $shift  = 0;
  875.         $result = 0;
  876.  
  877.         for ($i = 0; $i $len; ++$i{
  878.             $result |= (@ord($str[$i]<< $shift);
  879.             $shift  += 8;
  880.         }
  881.  
  882.         return $result;
  883.     }
  884.     // }}}
  885. }
  886.  
  887. ?>

Documentation generated on Mon, 11 Mar 2019 14:30:26 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.