python-nicefloat

Introduction

python-nicefloat is a Python module implementing an algorithm based on the paper "Printing Floating-Point Numbers Quickly and Accurately", by Robert G. Burger and R. Kent Dybvig.

The implemented algorithm will find the shortest, correctly rounded output string representing a decimal number that converts to the same internal binary floating-point number when read.

Examples

Static method returning a short and correctly rounding string:

>>> from nicefloat import nicefloat

>>> f = 1.1

>>> print repr(f)
1.1000000000000001
>>> print str(f)
1.1
>>> print nicefloat.str(f)
1.1

>>> print float(repr(f)) == f
True
>>> print float(str(f)) == f
True
>>> print float(nicefloat.str(f)) == f
True

Static method returning a not-so-short and correctly rounding string:

>>> f = 3.0/11

>>> print repr(f)
0.27272727272727271
>>> print str(f)
0.272727272727
>>> print nicefloat.str(f)
0.2727272727272727

>>> print float(repr(f)) == f
True
>>> print float(str(f)) == f
False
>>> print float(nicefloat.str(f)) == f
True

Using it as a numeric type is possible as well:

>>> f = 1.1
>>> f
1.1000000000000001
>>> f*2
2.2000000000000002

>>> f = nicefloat(1.1)
>>> f
1.1
>>> f*2
2.2
>>> -1.1+f*2
1.1
>>> type(-1.1+f*2)
<class 'nicefloat.nicefloat'>

>>> isinstance(nicefloat(1.1), float)
True

This is not decimal arithmetic

This module is about a shorter decimal representation for binary floating point numbers. It's not a module for decimal floating point arithmetic.

If you're looking for decimal floating point arithmetic in Python, check the decimal module.

Why not str()?

Because str() truncates the floating point number. In other words,

>>> f = 1.1000000000000002
>>> float(str(f)) == f
False

Why not repr()?

If you're happy with the repr() result for floats, use it. It's certainly faster.

Why nicefloat.str(1.1*3) is still 3.3000000000000003?

Because that's the appropriate form to represent the result of that operation. If you were expecting a result like 3.3, you'll probably be surprised to see the following:

>>> 1.1
1.1000000000000001
>>> 1.1*3
3.3000000000000003
>>> 3.3
3.2999999999999998
>>> 1.1*3 == 3.3
False

If you really want to see 1.1*3 == 3.3, you're looking for decimal floating point arithmetic.

Download

License

python-nicefloat is available under the LGPL.

Author

Gustavo Niemeyer <gustavo@niemeyer.net>


CategoryProject

python-nicefloat (last edited 2008-03-03 03:02:03 by GustavoNiemeyer)