-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfloat_fix.py
36 lines (29 loc) · 1.25 KB
/
float_fix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP
from io import BytesIO
def float_to_decimal(s):
"""Substitute Decimals for floats in a string of statements.
>>> from decimal import Decimal
>>> s = 'print(+21.3e-5*-.1234/81.7)'
>>> decistmt(s)
"print (+Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7'))"
The format of the exponent is inherited from the platform C library.
Known cases are "e-007" (Windows) and "e-07" (not Windows). Since
we're only showing 12 digits, and the 13th isn't close to 5, the
rest of the output should be platform-independent.
>>> exec(s) #doctest: +ELLIPSIS
-3.21716034272e-0...7
Output from calculations with Decimal should be identical across all
platforms.
>>> exec(decistmt(s))
-3.217160342717258261933904529E-7
"""
result = []
g = tokenize(BytesIO(s.encode("utf-8")).readline) # tokenize the string
for toknum, tokval, _, _, _ in g:
if toknum == NUMBER and "." in tokval: # replace NUMBER tokens
result.extend(
[(NAME, "Decimal"), (OP, "("), (STRING, repr(tokval)), (OP, ")")]
)
else:
result.append((toknum, tokval))
return untokenize(result).decode("utf-8")