Automatically add appropriate prefix to Quantity
EDITED to include Mr.Wizard's replacement for Switch
EDITED to cover additional cases
Roll your own:
quantityWithAppropriatePrefix[quant_Quantity] :=
Fold[UnitConvert[#1, #2] &, quant,
{"Imperial", "SI"}];
EDIT: As Kuba pointed out in a comment, this can be written more compactly as
quantityWithAppropriatePrefix[quant_Quantity] :=
Fold[UnitConvert, quant, {"Imperial", "SI"}];
quantityWithAppropriatePrefix /@
{Quantity[0.0000011, "Meter"],
Quantity[0.0000033, "Feet"]}
{Quantity[1.1, "Micrometers"], Quantity[1.00584, "Micrometers"]}
A brute force approach:
quantityWithAppropriatePrefix[quant_Quantity] :=
Module[{si = UnitConvert[quant, "SI"], mag,
log10Mag, multiplier},
mag = QuantityMagnitude[si];
log10Mag = Round[Log10[mag], 3];
multiplier = {"Yocto", "Zepto", "Atto", "Femto",
"Pico", "Nano", "Micro", "Milli", "", "kilo",
"Mega", "Giga", "Tera", "Peta", "Exa", "Zetta",
"Yatta"}[[log10Mag/3 + 9]];
Quantity[mag 10^-log10Mag, multiplier <> QuantityUnit[si]]];
quantityWithAppropriatePrefix /@ {Quantity[0.0000011, "Meter"],
Quantity[0.0000033, "Feet"]}
{Quantity[1.1, "Micrometers"], Quantity[1.00584, "Micrometers"]}
Partition[Table[quantityWithAppropriatePrefix[
Quantity[1.23*10^n, "Volt"]], {n, -25, 25}],
6] // Grid
Just a variant:
qf[u_] := Module[{rng = Range[-24, 24, 3],
multiplier = {"Yocto", "Zepto", "Atto", "Femto", "Pico", "Nano",
"Micro", "Milli", "", "Kilo", "Mega", "Giga", "Tera", "Peta",
"Exa", "Zetta", "Yatta"}, v, p},
v = QuantityMagnitude[u];
p = First@Nearest[rng, Log10[v]];
Quantity[
v 10^-p, (p /. Thread[rng -> multiplier]) <> QuantityUnit[u]]
]
This is a brute force solution, but seems to be more robust and does not require an internet connection, that I put together based on the other posts in this thread.
AutoSIPrefix[quant_Quantity] := (Module[
{prefixlist, prefixrules, siunitstring, pfloc, baseunit,
basequantity, mag, log10Mag, prefix, newunit},
prefixlist =
"kilo" | "mega" | "giga" | "tera" | "peta" | "exa" | "zetta" |
"yotta" | "deci" | "centi" | "milli" | "micro" | "nano" |
"pico" | "femto" | "atto" | "zepto" | "yocto";
prefixrules = {3 -> "Kilo", 6 -> "Mega", 9 -> "Giga",
12 -> "Tera", 15 -> "Peta", 18 -> "Exa", 21 -> "Zetta",
24 -> "Yotta", -1 -> "Deci", -2 -> "Centi", -3 -> "Milli", -6 ->
"Micro", -9 -> "Nano", -12 -> "Pico", -15 ->
"Femto" - 18 -> "Atto", -21 -> "Zepto", -24 -> "Yocto",
0 -> ""};
siunitstring = QuantityUnit[UnitConvert[quant, "SI"]];
pfloc =
StringPosition[siunitstring, prefixlist, IgnoreCase -> True];
baseunit =
If[Length[pfloc] == 1,
Capitalize[StringDrop[siunitstring, pfloc[[1]]]],
Capitalize[siunitstring]];
basequantity =
UnitConvert[quant,
Capitalize[StringDrop[siunitstring, pfloc[[1]]]]];
mag = QuantityMagnitude[basequantity];
log10Mag = Round[Log10[mag], 3];
prefix = log10Mag /. prefixrules;
newunit = Capitalize[ prefix <> ToLowerCase[baseunit]];
UnitConvert[quant, newunit]]);