1 #!/usr/bin/env python 2 3 """ 4 Floating point number objects. 5 6 Copyright (C) 2015, 2016, 2018, 2021 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from __builtins__.unicode import unicode 23 from native import isinstance as _isinstance, \ 24 int_float, is_int, \ 25 float_add, float_div, float_eq, float_ge, float_gt, \ 26 float_le, float_lt, float_mod, float_mul, float_ne, \ 27 float_neg, float_pow, float_str, float_sub, 28 29 class float: 30 31 "A floating point number abstraction." 32 33 def __init__(self, number_or_string=None): 34 35 "Initialise the integer with the given 'number_or_string'." 36 37 # NOTE: To be implemented. 38 39 pass 40 41 def __hash__(self): 42 43 "Return a value for hashing purposes." 44 45 return self 46 47 def _binary_op(self, op, other): 48 49 "Perform 'op' on this float and 'other' if appropriate." 50 51 if _isinstance(other, float): 52 return op(self, other) 53 elif is_int(other): 54 return op(self, int_float(other)) 55 else: 56 return NotImplemented 57 58 def _binary_op_rev(self, op, other): 59 60 "Perform 'op' on 'other' and this float if appropriate." 61 62 if _isinstance(other, float): 63 return op(other, self) 64 elif is_int(other): 65 return op(int_float(other), self) 66 else: 67 return NotImplemented 68 69 def __iadd__(self, other): 70 71 "Return a new float for the addition of this float and 'other'." 72 73 return self._binary_op(float_add, other) 74 75 def __isub__(self, other): 76 77 "Return a new float for the subtraction from this float of 'other'." 78 79 return self._binary_op(float_sub, other) 80 81 def __imul__(self, other): 82 83 "Return a new float for the multiplication of this float and 'other'." 84 85 return self._binary_op(float_mul, other) 86 87 def __idiv__(self, other): 88 89 "Return a new float for the division of this float by 'other'." 90 91 return self._binary_op(float_div, other) 92 93 def __imod__(self, other): 94 95 "Return a new float for the modulo of this float by 'other'." 96 97 return self._binary_op(float_mod, other) 98 99 def __ipow__(self, other): 100 101 "Return a new float for the exponentiation of this float by 'other'." 102 103 return self._binary_op(float_pow, other) 104 105 __add__ = __radd__ = __iadd__ 106 __sub__ = __isub__ 107 108 def __rsub__(self, other): 109 110 "Return a new float for the subtraction of this float from 'other'." 111 112 return self._binary_op_rev(float_sub, other) 113 114 __mul__ = __rmul__ = __imul__ 115 __div__ = __idiv__ 116 117 def __rdiv__(self, other): 118 119 "Return a new float for the division of 'other' by this float." 120 121 return self._binary_op_rev(float_div, other) 122 123 # NOTE: To be implemented. 124 125 def __floordiv__(self, other): pass 126 def __rfloordiv__(self, other): pass 127 def __ifloordiv__(self, other): pass 128 129 __mod__ = __imod__ 130 131 def __rmod__(self, other): 132 133 "Return a new float for the modulo of 'other' by this float." 134 135 return self._binary_op_rev(float_mod, other) 136 137 __pow__ = __ipow__ 138 139 def __rpow__(self, other): 140 141 "Return a new float for the exponentiation of 'other' by this float." 142 143 return self._binary_op_rev(float_pow, other) 144 145 def __lt__(self, other): 146 147 "Return whether this float is less than 'other'." 148 149 return self._binary_op(float_lt, other) 150 151 def __gt__(self, other): 152 153 "Return whether this float is greater than 'other'." 154 155 return self._binary_op(float_gt, other) 156 157 def __le__(self, other): 158 159 "Return whether this float is less than or equal to 'other'." 160 161 return self._binary_op(float_le, other) 162 163 def __ge__(self, other): 164 165 "Return whether this float is greater than or equal to 'other'." 166 167 return self._binary_op(float_ge, other) 168 169 def __eq__(self, other): 170 171 "Return whether this float is equal to 'other'." 172 173 return self._binary_op(float_eq, other) 174 175 def __ne__(self, other): 176 177 "Return whether this float is not equal to 'other'." 178 179 return self._binary_op(float_ne, other) 180 181 def __neg__(self): 182 183 "Apply the unary negation operator." 184 185 return float_neg(self) 186 187 def __pos__(self): 188 189 "Apply the unary positive operator." 190 191 return self 192 193 def __str__(self): 194 195 "Return a string representation." 196 197 return unicode(float_str(self)) 198 199 __repr__ = __str__ 200 201 def __bool__(self): 202 203 "Return whether this float is non-zero." 204 205 return float_ne(self, 0) 206 207 # vim: tabstop=4 expandtab shiftwidth=4