Created
August 12, 2016 20:59
-
-
Save kbrafford/da39e06d18b6df2a07777eecb4493699 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
EmbeddedExcellence.Formatting package | |
efloat module | |
Keith Brafford | |
Copyright (c) 2010 Embedded Excellence, Inc. | |
All Rights Reserved | |
''' | |
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.) | |
""" | |
precision = 4 | |
exponent_letter = "e" | |
def __init__(self, value = 0.0): | |
super(EFloat, self).__init__(value) | |
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): | |
exponent = self._exponent() | |
shift = exponent % 3 | |
pre = "".join(" " * (2-int(shift))) | |
if self >= 0.0: | |
pre = " " + pre | |
if exponent >= 0: | |
EFloat.format_string = pre + "%3." + ("%d" % EFloat.precision) + "f" + EFloat.exponent_letter + "+%02d" | |
else: | |
EFloat.format_string = pre + "%3." + ("%d" % EFloat.precision) + "f" + EFloat.exponent_letter + "-%02d" | |
retval = EFloat.format_string % (self._mantissa()*math.pow(10, shift), abs(self._exponent() - shift)) | |
return retval | |
def __str__(self): | |
return self._asEng() | |
def __repr__(self): | |
return str(self) | |
def __add__(self, x): | |
retval = EFloat(float.__add__(self, float(x))) | |
return retval | |
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))) | |
def format(number, specifier= None): | |
number = EFloat(number) | |
return str(number) | |
if __name__ == "__main__": | |
import math | |
number = math.pi ** 2 | |
for i in range(2,17): | |
EFloat.precision = i | |
for j in range(-20, 21): | |
print format(number * 10**j) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment