Problems with conversion of values in strings to integers

Bengt Richter bokr at oz.net
Wed Oct 8 17:29:06 EDT 2003


On Mon, 06 Oct 2003 14:06:26 +0200, Peter Otten <__peter__ at web.de> wrote:

>Jørgen Cederberg wrote:
>
>> Hi,
>> 
>> using Python 2.2.1 on Windows and QNX I'm having trouble understandig
>> why int() raises a ValueError exception upon converting strings.
>> 
>>  >>> int('-10')
>> -10
>>  >>> int('10')
>> 10
>>  >>> int(10.1)
>> 10
>>  >>> int('10.1')
>> Traceback (most recent call last):
>>    File "<stdin>", line 1, in ?
>> ValueError: invalid literal for int(): 10.1
>> 
>> This is quite frustating. The only solution I can see is to do:
>>  >>> int(float('10.1'))
>> 10
>> 
>> Is this the only solution or are there any other way to do this?
>
>
>There is more than one way to convert a string representing a fp number to
>an integer:
Indeed, but what if the OP wants something like C's atoi? E.g.,
(playing with MinGW and MSYS -- pretty neat, BTW ;-)

[14:35] /c/pywk/clp/atoi>cat pratoi.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
    if(argc<2){
        printf("Usage: pratoi strings ...\n");
    } else {
        int i;
        char sbuf[32];
        for(i=1;i<argc;++i){
            snprintf(sbuf,32,"'%s'",argv[i]);
            printf("%8s => %d\n", sbuf, atoi(argv[i]));
        }
    }
    return 0;
}
[14:35] /c/pywk/clp/atoi>gcc pratoi.c -o pratoi
[14:35] /c/pywk/clp/atoi>pratoi 0 1 -1 +1 123 4.5 -5.6 -1.2e3 0x11 011 "  -3xx" " -xx"
     '0' => 0
     '1' => 1
    '-1' => -1
    '+1' => 1
   '123' => 123
   '4.5' => 4
  '-5.6' => -5
'-1.2e3' => -1
  '0x11' => 0
   '011' => 11
'  -3xx' => -3
  ' -xx' => 0

Note the 'way different result on -1.2e3 in particular. Also does the OP want to ignor
octal and hex or reject them?

atoi looks like it just strips leading spaces, takes and optional sign, and computes
a decimal from as many decimal digits as it can then find (including none as ok).

I'll leave that as an exercise for python ;-)

>
>>>> int(float("1.999"))
>1
>
>>>> int(round(float("1.999")))
>2
>
>I think it's good that Python does not make the decision for you. Once you
>have decided which route to go you can easily wrap it into a helper
>function, e. g.
>
>def toInt(s):
>    try:
>        return int(s)
>    except ValueError:
>        return int(round(float(s)))
>
>(When dealing with user input, things are a little more complicated, as the
>decimal separator changes between locales)
>
There's that too ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list