7
$\begingroup$

I have a number of val = 0.000015783 which represents a current value in Amps.

I want to display it with 3 significant digits and with SI prefixes instead of the usual power notation. So the target result is: 15.8µ

The closest I can get to is:

EngineeringForm[val, 3]

which yields: 15.8x10^-6. However I can't find a way to replace to x10^-6 with a µ.

I also couldn't find any way to do it using the Quantity function.

Thank you in advance.

$\endgroup$

4 Answers 4

6
$\begingroup$

UnitConvert, Quantity, and SetPrecision can convert a numerical value of amperes to µA with 3 significant digits.

val = 0.000015783;
UnitConvert[Quantity[SetPrecision[val, 3],"Amperes"],"MicroAmperes"]
(* 15.8 µA *)

Change the amperes quantity to a string with StringReplace and TextString.

StringReplace["A"|" "->""]@TextString@
  UnitConvert[Quantity[SetPrecision[val,3],"Amperes"],"MicroAmperes"]
(* 15.8µ *)

We can use these methods for a function that converts a numerical ampere value to a quantity value with an SI prefix and designated number of significant digits. The function selects the SI prefix that corresponds to engineering notation. Values outside of the known prefixes are converted to amperes and adjusted for precision, but without a prefix.

sciPrefix[n_, sd_?IntegerQ] := Module[{
  prefix = Switch[Quotient[Log10[n], 3], 0,"",-1,"Milli",-2,"Micro",-3,"Nano"],
  v = SetPrecision[Quantity[n, "Amperes"], sd]},
  If[Head[prefix] === String,
    UnitConvert[v, prefix<>"Amperes"],
    v]]

Then:

sciPrefix[val, 3]
(* 15.8 µA *)

Table[sciPrefix[val*Power[10,e], 3], {e,-5,8}](* etc. *)

Add the string conversion steps to convert a numeric ampere value to a formatted string.

sciPrefixText[n_, sd_?IntegerQ] := Module[{
  prefix = Switch[Quotient[Log10[n], 3], 0,"",-1,"Milli",-2,"Micro",-3,"Nano"],
  v = SetPrecision[Quantity[n, "Amperes"], sd]},
  StringReplace["A"|" "->""]@TextString@If[Head[prefix]===String,
    UnitConvert[v, prefix<>"Amperes"],
    v]]

sciPrefixText[val, 3]
(* 15.8µ *)
sciPrefixText[val, 4]
(* 15.78µ *)

It’s easy to add SI prefixes by changing Switch. For example,

Switch[Quotient[Log10[n], 3], 1,”Kilo”,0,””,-1,”Milli”,-2,”Micro”,-3,”Nano”,-4,”Pico”]

Where the numbers are the integer powers of 1000 and the matching prefixes from mathworld.wolfram.com/SIPrefixes.html.

$\endgroup$
1
  • $\begingroup$ thanks for the comprehensive answer. I don't use all parts of it but it is a solid starting point for many associated problems. $\endgroup$
    – tobalt
    Oct 27, 2020 at 7:48
6
$\begingroup$

Perhaps you can use the following to produce a Quantity object:

val=0.000015783;
UnitConvert[val, "Micro"]

15.783𝜇

$\endgroup$
1
  • $\begingroup$ thanks. This is the type of integration I was looking for. Looks like Quantity does understand the concept of SI prefixes. $\endgroup$
    – tobalt
    Oct 27, 2020 at 7:19
3
$\begingroup$

Something like:

si[val0_] := Module[{val = val0, count = 0},
  If[Abs@val > 1,
   While[Abs@val >= 10^3, count++; val /= 10^3];
   pre = Switch[count, 1, "k", 2, "mega", 3, "giga", 4, "tera", _, ""]
   ,
   While[Abs@val < 1, count++; val *= 10^3];
   pre = Switch[count, 1, "mili", 2, "\[Mu]", 3, "nano", 4, "pico", _,
      ""]
   ];
  StringForm["`` ``", NumberForm[val, 3], pre]
  ]

si[15.8 10^-6]
 15.8 μ

Note, the output is only for display, you can not use it for further calculations.

$\endgroup$
1
  • $\begingroup$ Thanks. It works but my feeling is that there is a more elegant way. And with the clumsy Wolfram syntax, we are all looking for more elegance, arent we ? :) Reason is, that this page exists, which lets me hope for a hidden direct integration in Mathematica: mathworld.wolfram.com/SIPrefixes.html I'll mark you as Answer, if that should turn out to be not the case $\endgroup$
    – tobalt
    Oct 26, 2020 at 12:08
3
$\begingroup$

I think EngineeringForm will do the job if it is given the right formatting function.

Consider

munger[m_, b_, e_] :=
  Switch[e,
    "-3", m <> "m",
    "-6", m <> "μ",
    "-9", m <> "n",
    "", m,
    _, Row[{m, "×", Superscript[b, e]}]]
EngineeringForm[1.57831×10^Range[4, -10, -1], 3, NumberFormat -> munger]
{15.8×10^3, 1.58×10^3, 158., 15.8, 1.58, 158.m, 15.8m, 1.58m, 
 158.μ, 15.8μ, 1.58μ, 158.n, 15.8n, 1.58n, 158.×10^-12}

Will that work for you?

$\endgroup$
5
  • $\begingroup$ thanks for pointing me to NumberFormat, which looks very powerful. It is very elegant. I took the m<> in front of Switch to make it even nicer. Still, I like the integration with Quantity even more as it feels more native. So I will set creidhes post as the answer. $\endgroup$
    – tobalt
    Oct 27, 2020 at 7:42
  • $\begingroup$ (Sorry can't edit anymore) Also, when passing a Quantity object to EngineeringForm, there'll be an ugly space between e.g. µ and A, which is avoided when using the prefix also within Quantity $\endgroup$
    – tobalt
    Oct 27, 2020 at 7:52
  • $\begingroup$ @tobalt. It is just my opinion, but I don't like the idea of trying to integrate Quantity with this approach. Everything passed into a formatting function is a string and its output is expected to be a string. Quantity objects are not strings. $\endgroup$
    – m_goldberg
    Oct 27, 2020 at 8:40
  • $\begingroup$ (the @ statement keeps getting deleted...) Indeed. This and Quantity don't harmonize well. Even though I marked another post as answer, I am still using this (for an automatic Legend display). I just place the unit string "A" into the format string to make it work. $\endgroup$
    – tobalt
    Oct 27, 2020 at 9:09
  • $\begingroup$ @tobalt. @ callouts get deleted if the person named has not made a comment to the post where you are commenting. $\endgroup$
    – m_goldberg
    Oct 29, 2020 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.