Initial commit
This commit is contained in:
86
src/Scientific/Quantity.php
Normal file
86
src/Scientific/Quantity.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Scientific;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
abstract class Quantity
|
||||
{
|
||||
/*
|
||||
* https://en.wikipedia.org/wiki/Metric_prefix
|
||||
*/
|
||||
private const METRIC_PREFIXES = [
|
||||
'yotta' => 'Y',
|
||||
'zetta' => 'Z',
|
||||
'exa' => 'E',
|
||||
'peta' => 'P',
|
||||
'tera' => 'T',
|
||||
'giga' => 'G',
|
||||
'mega' => 'M',
|
||||
'kilo' => 'k',
|
||||
'hecto' => 'h',
|
||||
'deca' => 'da',
|
||||
'unit' => '',
|
||||
'deci' => 'd',
|
||||
'centi' => 'c',
|
||||
'milli' => 'm',
|
||||
'micro' => 'μ',
|
||||
'nano' => 'n',
|
||||
'pico' => 'p',
|
||||
'femto' => 'f',
|
||||
'atto' => 'a',
|
||||
'zepto' => 'z',
|
||||
'yocto' => 'y',
|
||||
];
|
||||
|
||||
abstract protected function getSymbol(): string;
|
||||
|
||||
abstract protected function getName(): string;
|
||||
|
||||
public function __construct(
|
||||
private Unit $value
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
final public static function fromValue(float $value): static
|
||||
{
|
||||
return new static(new Unit($value));
|
||||
}
|
||||
|
||||
final public function getValue(): Unit
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
final public function format(string $prefix = 'auto'): string
|
||||
{
|
||||
if ($prefix === 'auto') {
|
||||
$prefix = $this->getAppropriatePrefix();
|
||||
} else if (!method_exists($this->value, $prefix)) {
|
||||
throw new InvalidArgumentException('Invalid size: ' . $prefix);
|
||||
}
|
||||
|
||||
$value = $this->value->{$prefix}();
|
||||
$prefix = self::METRIC_PREFIXES[$prefix] ?? '?';
|
||||
$symbol = $this->getSymbol();
|
||||
|
||||
return sprintf('%.3g %s%s', $value, $prefix, $symbol);
|
||||
}
|
||||
|
||||
private function getAppropriatePrefix(): string
|
||||
{
|
||||
foreach (array_keys(self::METRIC_PREFIXES) as $prefix) {
|
||||
$value = $this->value->{$prefix}();
|
||||
if ($value >= 1. && $value < 1000.) {
|
||||
return $prefix;
|
||||
}
|
||||
}
|
||||
return 'unit';
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->format();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user