-
Notifications
You must be signed in to change notification settings - Fork 102
Floating point and SI units
This page is for working with floating point numbers, where additional tricks are shown for numbers with SI units.
Say you want to write something like this:
\begin{pylabcode}
R = 50
V = 1.42
I = V/R
\end{pylabcode}
The current through a \pylab{R} $\Omega$ resistor is \pylab{I} $A$
The result would then be:
The current through a 50 $\Omega$ resistor is 0.028399999999999998 $A$
which isn't very attractive. To get the right number of significant digits, the following might be useful:
def n(num, sig=3):
f = '%.' + str(sig) + 'g'
ret = f % num
return ret
Which would produce 0.0285 instead.
For larger number one can either add the following in the latex preamble:
\providecommand{\e}[1]{\ensuremath{\times 10^{#1}}} % scientific notation
and adjust the python code to
def n(num, sig=3):
f = '%.' + str(sig) + 'g'
ret = f % num
if 'e' in ret:
ret = ret.replace('e', r'\e{'
ret += '}'
return ret
Which might produce something like 4.2x10^10.
Alternatively one might want numbers to have the correct SI prefix (G, M, k, m, micro), in which case the following can be utilized.
from math import log10
def n(num, sig=3):
f = '%.' + str(sig) + 'g'
ret = f % num
return ret
def eUnit(num):
''' Takes a float n and returns scaled version and a SI prefix. Invalid input returns the input'''
unit = {9: 'G', 6: 'M', 3: 'k', 0: '',
-3: 'm', -6: '\\textmu', -9: 'n', -12: 'p', -15: 'f', -18: 'a', -21: 'z'}
try:
x = int(log10(n)//3)*3
u = unit[x]
except (ValueError, KeyError):
x = 0
return n/10**x, unit[x]
def si(num, unit='', sig=3, auto_scale=True):
if auto_scale:
num, siPrefix = eUnit(num)
siPrefix = siPrefix.replace('$', '')
else:
siPrefix = ''
num = n(num, sig=sig)
res = r'\SI{%s}{%s%s}' % (num, siPrefix, unit)
Which requires the following in the latex preamble:
\usepackage{siunitx}
The above example would then be
The current through a \pylab{si(R, r'\ohm')} resistor is \pylab{si(I, r'A')}.
Producing
The current through a \SI{50}{\ohm} resistor is \SI{28.4}{mA}
If you find ourself typing this allot, you can define your own latex command like this
\providecommand{\psi}[1]{\pylab{si(#1)}}
The current through a \psi{R, r'\ohm'} resistor is \psi{I, r'A'}.