[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