|
8 | 8 |
|
9 | 9 | from decimal import Decimal, localcontext |
10 | 10 | from fractions import Fraction |
| 11 | +from warnings import warn |
11 | 12 |
|
12 | 13 | from tivars.data import * |
13 | 14 | from tivars.models import * |
@@ -171,7 +172,7 @@ def load_float(self, decimal: float): |
171 | 172 | :param decimal: The float to load |
172 | 173 | """ |
173 | 174 |
|
174 | | - self.load_decimal(Decimal(decimal)) |
| 175 | + self.load_decimal(Decimal(str(decimal))) |
175 | 176 |
|
176 | 177 | def json_number(self) -> float | str: |
177 | 178 | """ |
@@ -252,36 +253,23 @@ def load_string(self, string: str, **kwargs): |
252 | 253 | # Normalize string |
253 | 254 | string = replacer(squash(string).upper(), {"~": "-", "|E": "E"}) |
254 | 255 |
|
255 | | - if "E" not in string: |
256 | | - string += "E0" |
| 256 | + # Let Decimal handle it |
| 257 | + self.sign_bit, digits, exponent = TI_CONTEXT.create_decimal(string).as_tuple() |
257 | 258 |
|
258 | | - if "." not in string: |
259 | | - string = string.replace("E", ".E") |
| 259 | + if not isinstance(exponent, int): |
| 260 | + raise OverflowError("cannot create real number from ±inf") |
260 | 261 |
|
261 | | - neg = string.startswith("-") |
262 | | - string = string.strip("+-") |
| 262 | + elif digits == (0,): |
| 263 | + self.mantissa = 0 |
| 264 | + self.exponent = 0x80 |
263 | 265 |
|
264 | | - # Obtain integer and decimal parts |
265 | | - number, exponent = string.split("E") |
266 | | - integer, decimal = number.split(".") |
267 | | - integer, decimal = integer or "0", decimal or "0" |
268 | | - |
269 | | - if int(integer) == int(decimal) == 0: |
270 | | - self.mantissa, self.exponent, self.sign_bit = 0, 0x80, neg |
271 | | - return |
272 | | - |
273 | | - # Adjust exponent to make integer mantissa |
274 | | - exponent = int(exponent or "0") |
275 | | - while not 0 < (value := int(integer)) < 10: |
276 | | - if value == 0: |
277 | | - integer, decimal = decimal[0], decimal[1:] |
278 | | - exponent -= 1 |
279 | | - |
280 | | - else: |
281 | | - integer, decimal = integer[:-1], integer[-1] + decimal |
282 | | - exponent += 1 |
| 266 | + else: |
| 267 | + self.mantissa = int("".join(map(str, digits)).ljust(14, "0")) |
| 268 | + self.exponent = exponent + (len(digits) - 1) + 0x80 |
283 | 269 |
|
284 | | - self.mantissa, self.exponent, self.sign_bit = int((integer + decimal).ljust(14, "0")[:14]), exponent + 0x80, neg |
| 270 | + if self.exponent < -29 or 227 < self.exponent: |
| 271 | + warn(f"Values with |exponent| > 99 raise errors when used for arithmetic.", |
| 272 | + UserWarning) |
285 | 273 |
|
286 | 274 |
|
287 | 275 | class TIUndefinedReal(TIReal, register=True): |
@@ -326,7 +314,7 @@ def __format__(self, format_spec: str) -> str: |
326 | 314 | def load_fraction(self, fraction: Fraction): |
327 | 315 | with localcontext() as ctx: |
328 | 316 | ctx.prec = 14 |
329 | | - decimal = Decimal(fraction.numerator) / fraction.denominator |
| 317 | + decimal = TI_CONTEXT.create_decimal(fraction.numerator) / fraction.denominator |
330 | 318 |
|
331 | 319 | super().load_string(str(decimal)) |
332 | 320 |
|
|
0 commit comments