24 self::ENGLISH => array(
29 self::METRIC => array(
'pt',
'0.352777778',
'mm'),
31 self::METRIC => array(
34 self::ENGLISH => array(
'mm',
'2.83464567',
'pt'),
56 public function __construct($output_precision = 4, $internal_precision = 10, $force_no_bcmath =
false)
58 $this->outputPrecision = $output_precision;
59 $this->internalPrecision = $internal_precision;
60 $this->bcmath = !$force_no_bcmath && function_exists(
'bcmul');
82 public function convert($length, $to_unit)
84 if (!$length->isValid()) {
89 $unit = $length->getUnit();
91 if (
$n ===
'0' || $unit ===
false) {
95 $state = $dest_state =
false;
96 foreach (self::$units as $k => $x) {
97 if (isset($x[$unit])) {
100 if (isset($x[$to_unit])) {
104 if (!$state || !$dest_state) {
111 if ($sigfigs < $this->outputPrecision) {
119 $log = (int)floor(log(abs(
$n), 10));
120 $cp = (
$log < 0) ? $this->internalPrecision -
$log : $this->internalPrecision;
122 for ($i = 0; $i < 2; $i++) {
125 if ($dest_state === $state) {
127 $dest_unit = $to_unit;
130 $dest_unit = self::$units[$state][$dest_state][0];
134 if ($dest_unit !== $unit) {
135 $factor = $this->
div(self::$units[$state][$unit], self::$units[$state][$dest_unit], $cp);
136 $n = $this->
mul(
$n, $factor, $cp);
148 if ($dest_state === $state) {
161 $n = $this->
mul(
$n, self::$units[$state][$dest_state][1], $cp);
162 $unit = self::$units[$state][$dest_state][2];
163 $state = $dest_state;
170 if ($unit !== $to_unit) {
179 if (strpos(
$n,
'.') !==
false) {
194 $n = ltrim(
$n,
'0+-');
195 $dp = strpos(
$n,
'.');
197 $sigfigs = strlen(rtrim(
$n,
'0'));
199 $sigfigs = strlen(ltrim(
$n,
'0.'));
214 private function add($s1, $s2, $scale)
217 return bcadd($s1, $s2, $scale);
219 return $this->
scale((
float)$s1 + (
float)$s2, $scale);
230 private function mul($s1, $s2, $scale)
233 return bcmul($s1, $s2, $scale);
235 return $this->
scale((
float)$s1 * (
float)$s2, $scale);
246 private function div($s1, $s2, $scale)
249 return bcdiv($s1, $s2, $scale);
251 return $this->
scale((
float)$s1 / (
float)$s2, $scale);
264 $new_log = (int)floor(log(abs(
$n), 10));
265 $rp = $sigfigs - $new_log - 1;
266 $neg =
$n < 0 ?
'-' :
'';
269 $n = bcadd(
$n, $neg .
'0.' . str_repeat(
'0', $rp) .
'5', $rp + 1);
270 $n = bcdiv(
$n,
'1', $rp);
274 $n = bcadd(
$n, $neg .
'5' . str_repeat(
'0', $new_log - $sigfigs), 0);
275 $n = substr(
$n, 0, $sigfigs + strlen($neg)) . str_repeat(
'0', $new_log - $sigfigs + 1);
279 return $this->
scale(
round(
$n, $sigfigs - $new_log - 1), $rp + 1);
294 $r = sprintf(
'%.0f', (
float)$r);
299 $precise = (string)
round(substr($r, 0, strlen($r) + $scale), -1);
301 return substr($precise, 0, -1) . str_repeat(
'0', -$scale + 1);
303 return sprintf(
'%.' . $scale .
'f', (
float)$r);