Last active
January 3, 2016 22:09
-
-
Save tejainece/8526165 to your computer and use it in GitHub Desktop.
Fixed point arithmetic library fro Python. I developed this to aid me in studying Circuit perspective of Computer Arithmetic.
This file contains hidden or 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
| def bin_complement(a): | |
| tmpBin = list(a) | |
| for i, c in enumerate(tmpBin): | |
| if c == "1": | |
| tmpBin[i] = "0" | |
| else: | |
| tmpBin[i] = "1" | |
| return ''.join(tmpBin) | |
| def bin_increment(a): | |
| tmpBin = list(a) | |
| for i, c in enumerate(tmpBin[::-1]): | |
| if c == "0": | |
| tmpBin[-i-1] = "1" | |
| break | |
| else: | |
| tmpBin[-i-1] = "0" | |
| return ''.join(tmpBin) | |
| class FixedPoint: | |
| _data = "" # actual data | |
| _significant_width = 0 # Width of significant part | |
| _fraction_width = 0 # Width of part | |
| def __init__(self, significant_width, fraction_width): | |
| self._significant_width = significant_width | |
| self._fraction_width = fraction_width | |
| def total_width(self): | |
| return self._significant_width + self._fraction_width | |
| def get_number(self): | |
| tStr = self._data | |
| tData = 0.0 | |
| neg = tStr[0] == "1" | |
| if neg: | |
| tStr = bin_complement(tStr) | |
| tStr = bin_increment(tStr) | |
| for i, c in enumerate(tStr[::-1]): | |
| if c == "1": | |
| pow_val = i - self._fraction_width | |
| tData = tData + (2**pow_val) | |
| if neg: | |
| tData = -tData | |
| return tData | |
| def _dec2bin(self, dec, tot_width): | |
| tStr = bin(dec & int("1" * tot_width, 2))[2:] | |
| tStr = ("0" * (tot_width - len(tStr))) + tStr | |
| return tStr | |
| def get_binary_string(self): | |
| return self._data | |
| # print the fixed point number in binary with a binary point | |
| def print_bin(self): | |
| data = self._data | |
| data_str = "0" | |
| if self._significant_width > 0: | |
| data_str = data[:self._significant_width] | |
| if self._fraction_width > 0: | |
| data_str = data_str + '.' + data[-self._fraction_width:] | |
| print data_str | |
| def from_number(self, data): | |
| #Python doesn't allow float to binary conversion | |
| #We multiply the data with 2^fraction_part and convert it to int | |
| #Now we can use built in format function on int to convert to binary | |
| tData = int(data * (2**self._fraction_width)) | |
| #We only need total_width number of binary bits | |
| data_str = self._dec2bin(tData, self.total_width()) | |
| self._data = data_str | |
| return True | |
| def from_binary_str(self, data): | |
| if len(data) != self.total_width(): | |
| return False | |
| self._data = data | |
| return True | |
| #operators | |
| #Addition operator | |
| def __add__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() + other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return self.get_number() + other | |
| else: | |
| return 0 | |
| def __radd__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() + other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return self.get_number() + other | |
| else: | |
| return 0 | |
| def __sub__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() - other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return self.get_number() - other | |
| else: | |
| return 0 | |
| def __rsub__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() - other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return other - self.get_number() | |
| else: | |
| return 0 | |
| def __mul__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() * other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return self.get_number() * other | |
| else: | |
| return 0 | |
| def __rmul__(self, other): | |
| if isinstance(other, FixedPoint): | |
| return self.get_number() * other.get_number() | |
| elif isinstance(other, int) or isinstance(other, float): | |
| return self.get_number() * other | |
| else: | |
| return 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment