0

I'm working on a school project that requires me to do some math on single-precision floating point numbers. I thought I would use the float32 format in numpy as python is really the only general purpose language I know. IMO this number format should be able to handle the number 1.0000001, but it keeps truncating my answer to 1.0. The closest I can get it to handle is 1.00001. Can anyone shed any light on this? I'm new to this floating point format and Python.

import numpy as np

keyInput=np.float32(input("Enter a number and i'll float 32 it: "))
print(keyInput)
print(np.float32(keyInput))
print("This is of type: ",type(keyInput))

input('Press ENTER to exit')
Cong Ma
  • 10,692
  • 3
  • 31
  • 47
Austin
  • 75
  • 1
  • 9
  • you should read about floating point numbers also try `Decimal("1.0000001")` ... the only time you will get a float that is exact is if the decimal part is equal exactly to `1/(2**n)` – Joran Beasley Sep 14 '15 at 20:01
  • I'm going for IEEE 754 format and using http://www.h-schmidt.net/FloatConverter/IEEE754.html as a guide. – Austin Sep 14 '15 at 20:03
  • 1
    As you've specified single precision floating point numbers - this is almost certainly exactly the kind of thing you're supposed to be finding. If you want to read into it - this is a good guide http://floating-point-gui.de/formats/fp/ – J Richard Snape Sep 14 '15 at 20:03
  • 1
    This is more thorough, if you enjoy reading tech documents http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – J Richard Snape Sep 14 '15 at 20:05
  • lol thats why I deleted it :P – Joran Beasley Sep 14 '15 at 20:09
  • I appreciate the clues you are giving, I've been reading up on floating point all day, built an excel spreadsheet to calculate floating point single precision, and IMO 1.0000001 is not too precise for this format, which also is supported by the link I have in my first comment that converts.32 bits can encode that number. – Austin Sep 14 '15 at 20:11
  • I have verified that the (approximate) full precision of that value can be stored. It is an issue on output. – Ignacio Vazquez-Abrams Sep 14 '15 at 20:18
  • yeah - you're right - I was too quick to guess - the answer has the issue right and some nice examples. – J Richard Snape Sep 14 '15 at 20:19
  • So I think the formatting issue masked another issue. I'm going to post a new question. Thanks everyone. – Austin Sep 14 '15 at 20:41

1 Answers1

5

First of all, print without explicit formatting or conversion is not reliable. You should try something like print "%.10f" % number instead of print number.

Second, as commentators have pointed out, you can't expect all decimal numbers gets represented precisely as floating point number. Read the Goldberg paper. It's a must read.

An example ipython session for you (I'm using Python 2.7, if you use Python 3, print is a function):

In [1]: import numpy

In [2]: print numpy.float32(1.0 + 1e-7)
1.0

In [3]: print "%.10f" % numpy.float32(1.0 + 1e-7)
1.0000001192

In [4]: print "%.10f" % numpy.float32(1.0 + 1e-8)
1.0000000000

Edit: you can use numpy to inspect type precision limits. Consult the doc of numpy.MachAr for more.

Example:

In [1]: import numpy

In [2]: machar = numpy.MachAr(float_conv=numpy.float32)

In [3]: machar.eps
Out[3]: 1.1920928955078125e-07
Cong Ma
  • 10,692
  • 3
  • 31
  • 47
  • Good call on the print formatting – J Richard Snape Sep 14 '15 at 20:18
  • The print format tip has been the most helpful so far. numpy.float32(1.0 + 1e-8) should just be 1.00000000 because it is not representable in single precision binary. For some reason the print command is not showing the full numpy.float32(1.0 + 1e-7). I'm wondering though now if float32 is somehow still using 64 bits, as the value being returned is the double precision value. (made some edits for bad grammar) – Austin Sep 14 '15 at 20:32
  • @Austin No. Why do you think "the value being returned is the double precision value"? – Cong Ma Sep 14 '15 at 20:34
  • I drop my number into this wonderful machine. http://www.h-schmidt.net/FloatConverter/IEEE754.html, when I print out the full value (I went ahead and did 40 decimal points) I get the double precision value. – Austin Sep 14 '15 at 20:37
  • 1
    @Austin This is because as Python does float-to-string conversion when substituting `"%f"`, it promotes (explicitly!) the numerical argument to double first and use that for formatting. See: https://github.com/python/cpython/blob/2.7/Objects/stringobject.c#L3965 – Cong Ma Sep 14 '15 at 20:43
  • Awesome comment, thank you. I'm going in circles here. Anyone know how to print out the full length but keep in float32? – Austin Sep 14 '15 at 20:52
  • 1
    @Austin You need a float-to-string conversion algorithm. If Python's implementation is not giving you all you need, you can roll your own. See: http://stackoverflow.com/questions/7153979/algorithm-to-convert-an-ieee-754-double-to-a-string and references therein. – Cong Ma Sep 14 '15 at 20:54
  • You hit it, it is with the conversions, thank you so much. When i run interactively and not with a script using input() and print() I get the precision I would expect. – Austin Sep 14 '15 at 21:10