24         self::ENGLISH => array(
 
   29             self::METRIC => array(
'pt', 
'0.352777778', 
'mm'),
 
   31         self::METRIC => array(
 
   34             self::ENGLISH => array(
'mm', 
'2.83464567', 
'pt'),
 
   53     public function __construct($output_precision = 4, $internal_precision = 10, $force_no_bcmath = 
false) {
 
   54         $this->outputPrecision = $output_precision;
 
   55         $this->internalPrecision = $internal_precision;
 
   56         $this->bcmath = !$force_no_bcmath && function_exists(
'bcmul');
 
   77     public function convert($length, $to_unit) {
 
   79         if (!$length->isValid()) 
return false;
 
   82         $unit = $length->getUnit();
 
   84         if (
$n === 
'0' || $unit === 
false) {
 
   88         $state = $dest_state = 
false;
 
   89         foreach (self::$units as $k => $x) {
 
   90             if (isset($x[$unit])) $state = $k;
 
   91             if (isset($x[$to_unit])) $dest_state = $k;
 
   93         if (!$state || !$dest_state) 
return false;
 
  104         $log = (int) floor(log(abs(
$n), 10));
 
  105         $cp = (
$log < 0) ? $this->internalPrecision - 
$log : $this->internalPrecision; 
 
  107         for ($i = 0; $i < 2; $i++) {
 
  110             if ($dest_state === $state) {
 
  112                 $dest_unit = $to_unit;
 
  115                 $dest_unit = self::$units[$state][$dest_state][0];
 
  119             if ($dest_unit !== $unit) {
 
  120                 $factor = $this->
div(self::$units[$state][$unit], self::$units[$state][$dest_unit], $cp);
 
  121                 $n = $this->
mul(
$n, $factor, $cp);
 
  133             if ($dest_state === $state) {
 
  146             $n = $this->
mul(
$n, self::$units[$state][$dest_state][1], $cp);
 
  147             $unit = self::$units[$state][$dest_state][2];
 
  148             $state = $dest_state;
 
  155         if ($unit !== $to_unit) 
return false;
 
  162         if (strpos(
$n, 
'.') !== 
false) 
$n = rtrim(
$n, 
'0');
 
  174         $n = ltrim(
$n, 
'0+-');
 
  175         $dp = strpos(
$n, 
'.'); 
 
  177             $sigfigs = strlen(rtrim(
$n, 
'0'));
 
  179             $sigfigs = strlen(ltrim(
$n, 
'0.')); 
 
  180             if ($dp !== 0) $sigfigs--;
 
  188     private function add($s1, $s2, $scale) {
 
  189         if ($this->bcmath) 
return bcadd($s1, $s2, $scale);
 
  190         else return $this->
scale($s1 + $s2, $scale);
 
  196     private function mul($s1, $s2, $scale) {
 
  197         if ($this->bcmath) 
return bcmul($s1, $s2, $scale);
 
  198         else return $this->
scale($s1 * $s2, $scale);
 
  204     private function div($s1, $s2, $scale) {
 
  205         if ($this->bcmath) 
return bcdiv($s1, $s2, $scale);
 
  206         else return $this->
scale($s1 / $s2, $scale);
 
  214         $new_log = (int) floor(log(abs(
$n), 10)); 
 
  215         $rp = $sigfigs - $new_log - 1; 
 
  216         $neg = 
$n < 0 ? 
'-' : 
''; 
 
  219                 $n = bcadd(
$n, $neg . 
'0.' .  str_repeat(
'0', $rp) . 
'5', $rp + 1);
 
  220                 $n = bcdiv(
$n, 
'1', $rp);
 
  224                 $n = bcadd(
$n, $neg . 
'5' . str_repeat(
'0', $new_log - $sigfigs), 0);
 
  225                 $n = substr(
$n, 0, $sigfigs + strlen($neg)) . str_repeat(
'0', $new_log - $sigfigs + 1);
 
  229             return $this->
scale(
round(
$n, $sigfigs - $new_log - 1), $rp + 1);
 
  236     private function scale($r, $scale) {
 
  240             $r = sprintf(
'%.0f', (
float) $r);
 
  245             $precise = (string) 
round(substr($r, 0, strlen($r) + $scale), -1);
 
  247             return substr($precise, 0, -1) . str_repeat(
'0', -$scale + 1);
 
  249         return sprintf(
'%.' . $scale . 
'f', (
float) $r);