4 ms·
Nitpicking, but this statement doesn't work with large numbers (which xrange() is supposed to handle correctly): self._len = int(ceil(float(stop - start) /
by sltkr 14y ago
Nitpicking, but this statement doesn't work with large numbers (which xrange() is supposed to handle correctly):
self._len = int(ceil(float(stop - start) / step))
Python supports arbitrary-length integers; you can't just cast those to (fixed-length) floating point numbers without losing precision. It's better to use integer division here, for example:
self._len = (stop - start)//step + bool((stop - start)%step)
(A variant like (stop - start + step - 1)//step works only for positive numbers; I guess it could work if you put it in the earlier if-clause and put a corresponding assignment with +1 at the end in the other branch.)
- dcrosta 14y agoGreat catch. If you want to submit a pull request on github you can get the credit -- github.com/dcrosta/xrange
- sltkr 14y agoThanks for the consideration, but I don't really use github, so you go ahead and take the credit yourself.
- dcrosta 14y agoOK, thanks. Updated in github and on the blog.
- graue 14y agoA related nitpick: since Python's integers are arbitrary size, technically operations like - and / are not constant time, so your claim of an implementation "with constant-time and constant-space operations" is not true. However, I understand if that complaint is just too nitpicky for you to want to mention it. Great post btw.
- dcrosta 14y agoHuh -- CPython 2.x doesn't let you create an xrange with values past 263-1. CPython 3.x does.
- sltkr 14y agoEven 63-bit integers aren't (all) representable in IEEE double floating point values (that Python uses) which have a 53 bits mantissa. For example, int(float(10¹⁸ - 1)) != 10¹⁸ - 1, but xrange(1, 10¹⁸) is perfectly valid (even in Python 2). edit: how do I type two consecutive asterisks on Hacker News? Backslash doesn't seem to work as an escape character.
- heretohelp 14y ago\\\\ Edit: failure. That's two stymied people :(
- deleted 14y ago[deleted]
- sp332 14y agoIf you put two spaces at the beginning of a line, you'll get a monospaced "literal" mode. For example, int(float(10**18 - 1)) != 10**18 - 1, but xrange(1, 10**18) is perfectly valid (even in Python 2).
- ori_b 14y agoYou can also cast to long, which doesn't lose precision.