[Tutor] Limitation of int() in converting strings
Oscar Benjamin
oscar.j.benjamin at gmail.com
Sat Dec 22 18:57:06 CET 2012
On 22 December 2012 02:06, Steven D'Aprano <steve at pearwood.info> wrote:
> On 18/12/12 01:36, Oscar Benjamin wrote:
>
>> I have often found myself writing awkward functions to prevent a
>> rounding error from occurring when coercing an object with int().
>> Here's one:
>>
>> def make_int(obj):
>> '''Coerce str, float and int to int without rounding error
>> Accepts strings like '4.0' but not '4.1'
>> '''
>> fnum = float('%s' % obj)
>> inum = int(fnum)
>> assert inum == fnum
>> return inum
>
> Well, that function is dangerously wrong. In no particular order,
> I can find four bugs and one design flaw.
I expected someone to object to this function. I had hoped that they
might also offer an improved version, though. I can't see a good way
to do this without special casing the treatment of some or other type
(the obvious one being str).
Although you have listed 5 errors I would have written the same list
as 2 errors:
1) You don't like my use of assert.
2) The function doesn't work for large numbers (bigger than around
100000000000000000).
I would also add:
3) It's ridiculous to convert types several times just to convert to
an integer without rounding.
Whether or not assert is appropriate depends on the context (although
I imagine that some people would disapprove of it always). I would say
that if you are using assert then it should really be in a situation
where you're not really looking to handle errors but just to abort the
program and debug when something goes wrong. In that context I think
that, far from being confusing, assert statements make it plainly
clear what the programmer who wrote them was meaning to do.
<snip>
> Lest you think that it is only humongous numbers where this is a
> problem, it is not. A mere seventeen digits is enough:
>
> py> s = "10000000000000001"
> py> make_int(s) - int(s)
> -1L
I think that most people would consider one hundred thousand million
million and one to be a fairly big number.
Oscar
More information about the Tutor
mailing list