<?php

function InitPrefixMultipliers()
{
  global $PrefixMultipliers;
$PrefixMultipliers = array
(
  'Binary' => array
  (
    'BaseIndex' => 0,
    'Definition' => array
    (
      array('', '', pow(2, 0)),
      array('Ki', 'kibi', pow(2, 10)),
      array('Mi', 'mebi', pow(2, 20)),
      array('Gi', 'gibi', pow(2, 30)),
      array('Ti', 'tebi', pow(2, 40)),
      array('Pi', 'pebi', pow(2, 50)),
      array('Ei', 'exbi', pow(2, 60)),
      array('Zi', 'zebi', pow(2, 70)),
      array('Yi', 'yobi', pow(2, 80)),
    ),
  ),
  'Decimal' => array
  (
    'BaseIndex' => 8,
    'Definition' => array
    (
      array('y', 'yocto', pow(10, -24)),
      array('z', 'zepto', pow(10, -21)),
      array('a', 'atto', pow(10, -18)),
      array('f', 'femto', pow(10, -15)),
      array('p', 'piko', pow(10, -12)),
      array('n', 'nano', pow(10, -9)),
      array('u', 'mikro', pow(10, -6)),
      array('m', 'mili', pow(10, -3)),
      array('', '', pow(10, 0)),
      array('k', 'kilo', pow(10, 3)),
      array('M', 'mega', pow(10, 6)),
      array('G', 'giga', pow(10, 9)),
      array('T', 'tera', pow(10, 12)),
      array('P', 'peta', pow(10, 15)),
      array('E', 'exa', pow(10, 18)),
      array('Z', 'zetta', pow(10, 21)),
      array('Y', 'yotta', pow(10, 24)),
    ),
  ),
  'Time' => array
  (
    'BaseIndex' => 8,
    'Definition' => array
    (
      array('ys', T('yoctosecond'), pow(10, -24)),
      array('zs', T('zeptosecond'), pow(10, -21)),
      array('as', T('attosecond'), pow(10, -18)),
      array('fs', T('femtosecond'), pow(10, -15)),
      array('ps', T('pikosecond'), pow(10, -12)),
      array('ns', T('nanosecond'), pow(10, -9)),
      array('us', T('microsecond'), pow(10, -6)),
      array('ms', T('millisecond'), pow(10, -3)),
      array('s', T('second'), 1),
      array(T('minutes'), T('minute'), 60),
      array(T('hours'), T('hour'), 60 * 60) ,
      array(T('days'), T('day'), 24 * 60 * 60),
      array(T('weeks'), T('week'), 7 * 24 * 60 * 60),
      array(T('months'), T('month'), 30 * 24 * 60 * 60),
      array(T('years'), T('year'), 364 * 24 * 60 * 60),
      array(T('decades'), T('decade'), 10 * 364 * 24 * 60 * 60),
      array(T('centuries'), T('century'), 100 * 364 * 24 * 60 * 60),
      array(T('millennia'), T('millennium'), 10000 * 364 * 24 * 60 * 60),
    ),
  ),
);
}

class PrefixMultiplier
{
  function TruncateDigits($Value, $Digits = 4)
  {
    for ($II = 2; $II > -6; $II--)
    {
      if ($Value >= pow(10, $II))
      {
        if ($Digits < ($II + 1)) $RealDigits = $II + 1;
          else $RealDigits = $Digits;
        $Value = round($Value / pow(10, $II - $RealDigits + 1)) * pow(10, $II - $RealDigits + 1);
        break;
      }
    }
    return $Value;
  }

  function Add($Value, $Unit, $Digits = 4, $PrefixType = 'Decimal')
  {
    global $PrefixMultipliers;

    $Negative = ($Value < 0);
    $Value = abs($Value);
    if (($Unit == '') and ($PrefixType != 'Time'))
      return $this->TruncateDigits($Value, $Digits);

    $I = $PrefixMultipliers[$PrefixType]['BaseIndex'];
    if ($Value == 0) return $Value.' '.$PrefixMultipliers[$PrefixType]['Definition'][$I][0].$Unit;

    if ($Value > 1)
    {
      while ((($I + 1) <= count($PrefixMultipliers[$PrefixType]['Definition'])) and (($Value / $PrefixMultipliers[$PrefixType]['Definition'][$I + 1][2]) > 1))
        $I = $I + 1;
    } else
    if ($Value < 1)
    {
      while ((($I - 1) >= 0) and (($Value / $PrefixMultipliers[$PrefixType]['Definition'][$I][2]) < 1))
        $I = $I - 1;
    }
    $Value = $Value / $PrefixMultipliers[$PrefixType]['Definition'][$I][2];

    // Truncate digits count
    $Value = $this->TruncateDigits($Value, $Digits);
    if ($Negative) $Value = -$Value;
    return $Value.' '.$PrefixMultipliers[$PrefixType]['Definition'][$I][0].$Unit;
  }
}

InitPrefixMultipliers();