...

View Full Version : ToMetric()



mjones74
12-09-2006, 06:51 AM
Hi friends, here is a sloppy function that converts an input value to metric power notation. It's limited to +/-2 billion or so and seems to work ok, but might contain bugs. Suggestions appreciated. :D



<?php

// integer to metric units notation "2125314" --> "2.13M"
function ToMetric($in) {
if (($in >= 1000000000) || ($in <= -1000000000)) {
$divs = 1000000000;
$mul = 'G';
} elseif (($in >= 1000000) || ($in <= -1000000)){
$divs = 1000000;
$mul = 'M';
} elseif (($in >= 1000) || ($in <= -1000)) {
$divs = 1000;
$mul = 'k';
} elseif (($in >= 1) || ($in <= -1)) {
$divs = 1;
$mul = '';

} elseif ($in >= 0.001) {
$divs = 0.001;
$mul = 'm';
} elseif ($in >= 0.000001) {
$divs = 0.000001;
$mul = 'u';
} elseif ($in >= 0.000000001) {
$divs = 0.000000001;
$mul = 'n';
} else {
return 0; // only thing left :)
}
$end = ($in / $divs); // result is ones-based, i.e. 1.95252242
$end = round($end,2); // 1.96
$end = strval($end); // "1.96"
$end = $end.$mul; // "1.96M"
return $end;
}

// test
echo '<pre>';
echo '2 Gigabytes : ' . ToMetric(2097152000) . 'B<br>';
echo '2,204,222 Ohms : ' . ToMetric(2204222) . '<br>';
echo '1,245 Hertz : ' . ToMetric(1245) . 'Hz<br>';
echo '-5,041 Volts : ' . ToMetric(-5041) . 'V<br>';
echo '0.00144 Watts : ' . ToMetric(0.00144) . 'W<br>';
echo '-584,046 Amps : ' . ToMetric(-584046) . 'A<br>';
echo '0.0000001592s : ' . ToMetric(0.0000001592) . 's<br>';
echo '15 Beakers : ' . ToMetric(15) . ' Flasks<br>';
echo '-2 Students : ' . ToMetric(-2) . ' F\'s<br>';
echo '0 Ice cubes : ' . ToMetric(0) . ' Frozen Things<br>';
echo '</pre>';

?>

Results:



2 Gigabytes : 2.1GB
2,204,222 Ohms : 2.2M
1,245 Hertz : 1.25kHz
-5,041 Volts : -5.04kV
0.00144 Watts : 1.44mW
-584,046 Amps : -584.05kA
0.0000001592s : 159.2ns
15 Beakers : 15 Flasks
-2 Students : -2 F's
0 Ice cubes : 0 Frozen Things

firepages
12-09-2006, 11:46 PM
A quick explanation of what metric power notation actually is may have helped ;) I was about to delete this post then it finally dawned on me ... I am getting on now but I am not the only slow one here ;)

PS : echo ToMetric('1000000000'); gives 1G ... which is right for teaspoons but (technically) wrong for bytes, perhaps some reference to base might help?

marek_mar
12-10-2006, 01:21 AM
Byte sizes are base 2 and have different names and abbreviations to distignuish them from the base 10 names and abbreviations. For example
1 GiB (gibibyte) is 1073741824bytes (2^30).
This is a relatively new standard and is not directly connected to the SI system (SI is not used in about 3 countries).

BTW the script is missing some prefixes: deca (da) 10^1, hecto (h) 10^2, deci (d) 10^-1 and centi (c) 10^-2.

mjones74
12-17-2006, 06:01 PM
Hi, here's an updated version. Are the new prefixes correct? Yes the GB example was probably not the best example. Thanks for looking.


<?php
// integer to metric power notation "2125314" --> "2.13M"
function ToMetric($in) {
if (($in >= 1000000000) || ($in <= -1000000000)) {
$divs = 1000000000;
$mul = 'G';
} elseif (($in >= 1000000) || ($in <= -1000000)){
$divs = 1000000;
$mul = 'M';
} elseif (($in >= 1000) || ($in <= -1000)) {
$divs = 1000;
$mul = 'k';
} elseif (($in >= 100) || ($in <= -100)) {
$divs = 100;
$mul = 'h';
} elseif (($in >= 10) || ($in <= -10)) {
$divs = 10;
$mul = 'da';

} elseif (($in >= 1) || ($in <= -1)) {
$divs = 1;
$mul = '';

} elseif ($in >= 0.1) {
$divs = 0.1;
$mul = 'd';
} elseif ($in >= 0.01) {
$divs = 0.01;
$mul = 'c';
} elseif ($in >= 0.001) {
$divs = 0.001;
$mul = 'm';
} elseif ($in >= 0.000001) {
$divs = 0.000001;
$mul = 'u';
} elseif ($in >= 0.000000001) {
$divs = 0.000000001;
$mul = 'n';
} else {
return '0'; // only thing left is zero
}
return strval(round(($in / $divs),2)).$mul;
}
?>

ralph l mayo
12-18-2006, 06:16 PM
A long chain of if cases is usually an indicator that a lookup table may be useful, eg:



function to_metric($num)
{
if ($num == 0)
{
return 0;
}
$postfixes = array(
'G' => 1000000000,
'M' => 1000000,
'k' => 1000,
'h' => 100,
'da' => 10,
'' => 1,
'd' => 0.1,
'c' => 0.01,
'm' => 0.001,
'u' => 0.000001,
'n' => 0.000000001
);
foreach ($postfixes as $postfix => $factor)
{
if ($num >= $factor)
{
return round($num / $factor, 2) . $postfix;
}
}
return $num;
}


After refactoring like that, all you have to do next time some wiseguy suggests a new suffix is add it to the table.

marek_mar
12-18-2006, 06:43 PM
After refactoring like that, all you have to do next time some wiseguy suggests a new suffix is add it to the table.
I heard that!

ralph l mayo
12-18-2006, 06:49 PM
I heard that!
hehe :p

mjones74
12-19-2006, 06:21 PM
Beautiful Ralph, thanks! :-)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum