I am considering writing a PEP for the inclusion of an engineering format specifier, and would appreciate input from others.
Background (for those who don't already know about engineering notation): Engineering notation (EN) is type of floating point representation. The idea with EN is that the powers of 10 are all multiples of 3, which correspond to the familiar Greek unit prefixes that engineers use when describing the different sizes of all sorts of real-world devices and phenomena: 1e-12 == pico 1e-9 == nano 1e-6 == micro 1e-3 == milli 1e+3 == kilo 1e+6 == mega 1e+9 == giga When people are talking about Ohms, Farads, Henries, Hz, and many others, they routinely have to normalize to EN. Fancy calculators from HP and TI routinely allow the users to go into engineering mode, but mysteriously things like C, Python, Excel, etc. don't For instance, no one talks about 4.7e-5F, as they would rather see 47e-6 (micro). Instead of 2.2e-2, engineers need to see 22.0e-3 (milli). Originally to address this issue, I wrote for myself an "EFloat" class that subclassed float: import math class EFloat(float): """EFloat(x) -> floating point number with engineering representation when printed Convert a string or a number to a floating point number, if possible. When asked to render itself for printing (via str() or print) it is normalized to engineering style notation at powers of 10 in multiples of 3 (for micro, milli, kilo, mega, giga, etc.) """ def __init__(self, value=0.0, prec=12): super(EFloat, self).__init__(value) self.precision = prec def _get_precision(self): return self._precision def _set_precision(self, p): self._precision = p self.format_string = "%3." + ("%d" % self._precision) + "fe% +d" return precision = property(_get_precision, _set_precision, doc="The number of decimal places printed") def _exponent(self): if self == 0.0: ret = 0 else: ret = math.floor(math.log10(abs(self))) return ret def _mantissa(self): return self/math.pow(10, self._exponent()) def _asEng(self): shift = self._exponent() % 3 retval = self.format_string % (self._mantissa()*math.pow(10, shift), self._exponent() - shift) return retval def __str__(self): return self._asEng() def __repr__(self): return str(self) def __add__(self, x): return EFloat(float.__add__(self, float(x))) def __radd__(self, x): return EFloat(float.__add__(self, float(x))) def __mul__(self, x): return EFloat(float.__mul__(self, float(x))) def __rmul__(self, x): return EFloat(float.__mul__(self, float(x))) def __sub__(self, x): return EFloat(float.__sub__(self, float(x))) def __rsub__(self, x): return EFloat(float.__rsub__(self, float(x))) def __div__(self, x): return EFloat(float.__div__(self, float(x))) def __rdiv__(self, x): return EFloat(float.__rdiv__(self, float(x))) def __truediv__(self, x): return EFloat(float.__truediv__(self, float(x))) def __rtruediv__(self, x): return EFloat(float.__rtruediv__(self, float(x))) def __pow__(self, x): return EFloat(float.__pow__(self, float(x))) def __rpow__(self, x): return EFloat(float.__rpow__(self, float(x))) def __divmod__(self, x): return EFloat(float.__divmod__(self, float(x))) def __neg__(self): return EFloat(float.__neg__(self)) def __floordiv__(self, x): return EFloat(float.__floordiv__(self, float(x))) which works well for working with interactive Python. There are places on the web where I've read that people have to work their butts off trying to "trick" Excel or OpenOffice to do engineering notation, or there is some work-around that is purported to work if you use the right version of the spreadsheet. After many months of using my EFloat class extensively with lots of apps dealing with embedded engineering tasks, it dawns on me that what we really need is simply a new format specifier. I am thinking that if we simply added something like %n (for eNgineer) to the list of format specifiers that we could make life easier for engineers: ("%n" % 12345) == "12.345e+03" ("%n" % 1234) == "1.234e+03" ("%n" % 123) == "123e+00" ("%n" % 1.2345e-5) == "12.345e+06" Of course, the normal dot fields would be put to use to allow us to specify how many total digits or digits of precision we wanted, or if we want zero prepend. (whatever makes the most sense, and keeps the standard most like what is already in the language): ("%.12n" % 12345678) == "12.345678000000e+06" Do you think this idea has enough merit to make it to PEP status? --Keith Brafford -- http://mail.python.org/mailman/listinfo/python-list