Skip to content

Commit 827b35c

Browse files
committed
Issue python#1580: New free format floating point representation based on "Floating-Point Printer Sample Code", by Robert G. Burger. For example repr(11./5) now returns '2.2' instead of '2.2000000000000002'.
Thanks to noam for the patch! I had to modify doubledigits.c slightly to support X64 and IA64 machines on Windows. I also added the new file to the three project files.
1 parent b9f7f24 commit 827b35c

9 files changed

Lines changed: 743 additions & 3 deletions

File tree

Include/floatobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
7676
*/
7777
PyAPI_FUNC(int) _PyFloat_Repr(double x, char *p, size_t len);
7878

79+
/* Used to get the important decimal digits of a double */
80+
PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum);
81+
PyAPI_FUNC(void) _PyFloat_DigitsInit(void);
82+
7983
/* The unpack routines read 4 or 8 bytes, starting at p. le is a bool
8084
* argument, true if the string is in little-endian format (exponent
8185
* last, at p+3 or p+7), false if big-endian (exponent first, at p).

Lib/test/test_float.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
import unittest, struct
3+
import os
34
from test import test_support
45

56
class FormatFunctionsTestCase(unittest.TestCase):
@@ -146,12 +147,26 @@ def test_format(self):
146147
self.assertRaises(ValueError, format, 3.0, "s")
147148

148149

150+
class ReprTestCase(unittest.TestCase):
151+
def test_repr(self):
152+
floats_file = open(os.path.join(os.path.split(__file__)[0],
153+
'floating_points.txt'))
154+
for line in floats_file:
155+
line = line.strip()
156+
if not line or line.startswith('#'):
157+
continue
158+
v = eval(line)
159+
self.assertEqual(v, eval(repr(v)))
160+
floats_file.close()
161+
162+
149163
def test_main():
150164
test_support.run_unittest(
151165
FormatFunctionsTestCase,
152166
UnknownFormatTestCase,
153167
IEEEFormatTestCase,
154-
FormatTestCase)
168+
FormatTestCase,
169+
ReprTestCase)
155170

156171
if __name__ == '__main__':
157172
test_main()

Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ OBJECT_OBJS= \
301301
Objects/genobject.o \
302302
Objects/fileobject.o \
303303
Objects/floatobject.o \
304+
Objects/doubledigits.o \
304305
Objects/frameobject.o \
305306
Objects/funcobject.o \
306307
Objects/iterobject.o \

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ What's New in Python 3.0a3?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #1580: New free format floating point representation based on
16+
"Floating-Point Printer Sample Code", by Robert G. Burger. For example
17+
repr(11./5) now returns '2.2' instead of '2.2000000000000002'.
18+
1519
- Issue #1573: Improper use of the keyword-only syntax makes the parser crash
1620

1721
- Issue #1564: The set implementation should special-case PyUnicode instead

0 commit comments

Comments
 (0)