我正在尝试创建一个数学函数(在 PHP 中),它将接受给定数量的公斤,并将它们转换为可读的形式,或者更好的是,返回最适合该数量的单位。输入始终为千克。最好是日志。
例如:
5 公斤 = (5) 公斤
0.5 公斤 = (500) 克
1000 公斤 = (1) 吨
0.001 千克 = (1) 克
0.0001 千克 = (100) 毫克
我知道有一种方法可以使用 log 或 log10 函数来做到这一点,但我无法弄清楚。
怎么办?
我认为这样的方法应该可行,但我相信有人可以提出更好的解决方案。
function outputWeight($kg)
{
$power = floor(log($kg, 10));
switch($power) {
case 5 :
case 4 :
case 3 : $unit = 'ton';
$power = 3;
break;
case 2 :
case 1 :
case 0 : $unit = 'kilogram';
$power = 0;
break;
case -1 :
case -2 :
case -3 : $unit = 'gram';
$power = -3;
break;
case -4 :
case -5 :
case -6 : $unit = 'milligram';
$power = -6;
break;
default : return 'out of range';
}
return ($kg / pow(10, $power)) . ' ' . $unit;
}
echo outputWeight(0.015) . '<br>';
echo outputWeight(0.15) . '<br>';
echo outputWeight(1.5) . '<br>';
echo outputWeight(15) . '<br>';
echo outputWeight(150) . '<br>';
这个想法是您可以轻松扩展范围。这将输出
15 gram
150 gram
1.5 kilogram
15 kilogram
150 kilogram
我没有彻底测试这段代码!
玩了一段时间后,这就是我的想法
function readableMetric($kg)
{
$amt = $kg * pow(1000, 3);
$s = array('mcg', 'mg', 'gm', 'kg','tonne');
$e = floor(log10($amt)/log10(1000));
return [
"amount" => $amt/pow(1000, $e),
"unit" => $s[$e]
];
}
以下函数在内部使用一个带有赋值单元 => 转换因子的数组。该阵列可以轻松扩展或修改以满足您自己的要求。该函数使用的固定限制为 1000。这意味着产值始终低于 1000,吨除外。通过预设为 2 的附加参数,可以更改最大小数位数。
function scaleKg(float $kg, int $decimalPlaces = 2) : string {
$scale = [
'micrograms' => 1.E9,
'milligram' => 1.E6,
'gram' => 1.E3,
'kilogram' => 1,
'ton' => 1.E-3,
];
foreach($scale as $unit => $factor){
$mass = $kg * $factor;
if($mass < 1000) {
return round($mass,$decimalPlaces).' '.$unit;
}
}
return round($mass,$decimalPlaces).' '.$unit;
}
一些例子:
$kg = 1.212345;
echo scaleKg($kg); //1.21 kilogram
$kg = 455;
echo scaleKg($kg); //455 kilogram
$kg = 0.0456;
echo scaleKg($kg); //45.6 gram
$kg = 23456;
echo scaleKg($kg); //23.46 ton
$kg = 23489000;
echo scaleKg($kg); //23489 ton
$kg = 167E-6;
echo scaleKg($kg); //167 milligram
我发现自己同意 Kiko 的观点,即最短的代码并不总是最好或最具可读性的。
考虑到将
log
带入其中似乎是不必要的复杂化。所以我建议我的原始代码的压缩版本:
function readableMetric($mass)
{
$units = [
-3 => "tonne",
0 => "kg",
3 => "g",
6 => "mg",
];
foreach ($units as $x => $unit) {
if ( ($newMass = $mass * 10 ** $x) >= 1 ) {
return "{$newMass} {$unit}";
}
}
}
这更具可扩展性(例如,您可以轻松添加
centigram
)
数学对大多数人来说都很直观(10 的幂)
如果你真的想要
golf
它,你可以将它缩小到一个衬垫:
function readableMetric($m)
{
foreach([-3=>"tonne",0=>"kg",3=>"g",6 =>"mg"] as $x=>$g)if(($n=$m*10**$x)>=1)return"$n $g";
}
你可以用一系列
if / else
语句来做到这一点吗?
$values = [
5, 0.5, 1000, 0.001, 0.0001
];
function convertmass($mass) : string
{
if ($mass >= 1000) {
return ($mass / 1000) . " ton";
}
elseif ($mass < 0.001) {
return ($mass * 1000000) . " mg";
}
elseif ($mass < 1) {
return ($mass * 1000 ) . " g";
}
else {
return $mass . " kg";
}
}
foreach ($values as $mass) {
echo convertmass($mass), PHP_EOL;
}
输出:
5 kg
500 g
1 ton
1 g
100 mg
如果您想要稍微更容易/更易读/更用户友好的更新来添加新的测量,那么您可以这样做:
$values = [
5, 0.5, 1000, 0.001, 0.0001
];
function convertmass($mass) : string
{
$massLookup = [
[ "unit" => "kg", "min" => 1, "max" => 1000, "multiple" => 1],
[ "unit" => "tonne", "min" => 1000, "max" => 1000000, "multiple" => 0.001],
[ "unit" => "g", "min" => 0.001, "max" => 1, "multiple" => 1000],
[ "unit" => "mg", "min" => 0.000001, "max" => 0.001, "multiple" => 1000000],
];
foreach ($massLookup as $unit) {
if ($mass >= $unit["min"] && $mass < $unit["max"]) {
return ($mass * $unit["multiple"]) . " {$unit["unit"]}";
}
}
return "Measurement {$mass} kg is out of range";
}
foreach ($values as $mass) {
echo convertmass($mass), PHP_EOL;
}