473,404 Members | 2,187 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

string.atoi and string.atol broken?

I think there may be a bug in string.atoi and string.atol. Here's some
output from idle.
Python 2.3.4 (#2, Jan 5 2005, 08:24:51)
[GCC 3.3.5 (Debian 1:3.3.5-5)] on linux2
Type "copyright", "credits" or "license()" for more information.

************************************************** **************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
************************************************** **************

IDLE 1.0.4
import string as s
s.atoi('2',3) 2 s.atoi('4',3)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in -toplevel-
s.atoi('4',3)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 4 s.atoi('12',11) 13 s.atoi('13',4) 7 s.atoi('12',4) 6 s.atoi('8',4)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
s.atoi('8',4)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 8


s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?

TIA,
Mike

Jul 18 '05 #1
19 7408
Mike Moum wrote:
I think there may be a bug in string.atoi and string.atol. Here's some
output from idle.

Python 2.3.4 (#2, Jan 5 2005, 08:24:51)
[GCC 3.3.5 (Debian 1:3.3.5-5)] on linux2
Type "copyright", "credits" or "license()" for more information.

************************************************** **************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
************************************************** **************

IDLE 1.0.4
>import string as s
>s.atoi('2',3)


2
>s.atoi('4',3)


Traceback (most recent call last):
File "<pyshell#2>", line 1, in -toplevel-
s.atoi('4',3)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 4
>s.atoi('12',11)


13
>s.atoi('13',4)


7
>s.atoi('12',4)


6
>s.atoi('8',4)


Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
s.atoi('8',4)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 8


s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?
[...]


That's not a bug, you'r missing something obvious.

The second parameter of string.atoi (or the int builtin)
is the base (or radix) in which the number you want to
convert is given.

For example string.atoi("777", 8) results in 511,
because 7 * 8**2 + 7 * 8**1 + 7 * 8**0 = 511.

Just out of curiosty:
What did you think what atoi does?
I don't understand how you came to expect that atoi('4',3)
should result in 11.
Bye,
Dennis
Jul 18 '05 #2
Mike Moum wrote:
> s.atoi('4',3)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in -toplevel-
s.atoi('4',3)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 4
What did you expect the value of '4' in base 3 to be? There is no '4'
in base 3... only '0', '1' and '2'.
> s.atoi('8',4)


Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
s.atoi('8',4)
File "/usr/lib/python2.3/string.py", line 220, in atoi
return _int(s, base)
ValueError: invalid literal for int(): 8


And no '8' in base 3 either.

Is this a bug, or am I missing something obvious?


Well, first of all, unless you're using a Python before 2.0, you're
missing that string.atoi is deprecated. You should be using int(),
which can take the same parameters.

I think secondly, you're missing that int(string, base) converts the
given string to an int assuming that the string is in the given base.
If the numbers you provide are out of the range of the digits that are
valid for that base, you will get an error.

Steve
Jul 18 '05 #3
Mike Moum wrote:
s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?


You and atoi() seem to disagree about the direction of the conversion, and
atoi() wins :-). It converts a string representation of a number into the
corresponding integer. The second parameter specifies in what base this
string is given.
You seem to want something like

import string

def itoa(n, base):
assert 2 <= base <= 16
if n < 0:
digits = ["-"]
n = -n
else:
digits = []
while n:
n, m = divmod(n, base)
digits.append(string.hexdigits[m])
digits.reverse()
return "".join(digits)

if __name__ == "__main__":
assert itoa(4, 3) == "11"
assert itoa(13, 4) == "31"
assert itoa(12, 4) == "30"
assert itoa(8, 4) == "20"
Peter
Jul 18 '05 #4
Peter Otten wrote:
Mike Moum wrote:
s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?
You and atoi() seem to disagree about the direction of the

conversion, and atoi() wins :-). It converts a string representation of a number into the corresponding integer. The second parameter specifies in what base this string is given.
You seem to want something like

import string

def itoa(n, base):
assert 2 <= base <= 16
Why have the restriction base <= 16? int() allows up to 36. All you
need to do is

BASE36_DIGITS = string.digits + string.lowercase

and change
digits.append(string.hexdigits[m]) to
digits.append(BASE36_DIGITS[m])


Jul 18 '05 #5
Dennis Benzinger wrote:
Just out of curiosty:
What did you think what atoi does?
I don't understand how you came to expect that atoi('4',3)
should result in 11.
Bye,
Dennis


Mea culpa. For some strange reason, I had it in my mind that atoi would
take a base ten number as a string and convert it to the correct
representation in the base of the second argument. In other words,
atoi('4',3) should take 4 in base 10 and convert it to base 3, resulting
in 11. Exactly backwords, as atoi('11',3) = 4, that is, 11 base 3 = 4
base 10.

Thanks to all for setting me straight.

Mike
Jul 18 '05 #6
Mike Moum wrote:
s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?


the function's named "atoi", not "atoitoa".

</F>

Jul 18 '05 #7
Peter Otten wrote:
Mike Moum wrote:

s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?

You and atoi() seem to disagree about the direction of the conversion, and
atoi() wins :-). It converts a string representation of a number into the
corresponding integer. The second parameter specifies in what base this
string is given.
You seem to want something like

import string

def itoa(n, base):
assert 2 <= base <= 16
if n < 0:
digits = ["-"]
n = -n
else:
digits = []
while n:
n, m = divmod(n, base)
digits.append(string.hexdigits[m])
digits.reverse()
return "".join(digits)

if __name__ == "__main__":
assert itoa(4, 3) == "11"
assert itoa(13, 4) == "31"
assert itoa(12, 4) == "30"
assert itoa(8, 4) == "20"


Huh - you remind me that I forgot to put the "show_base" Bengt and I came up
with into the ASPN cookbook. . .

Py> def show_base(val, base, min_digits=1, complement=False,
.... digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
.... if base > len(digits): raise ValueError("Not enough digits for base")
.... negative = val < 0
.... val = abs(val)
.... if complement:
.... sign = ""
.... max = base**min_digits
.... if (val >= max) or (not negative and val == max):
.... raise ValueError("Value out of range for complemented format")
.... if negative:
.... val = (max - val)
.... else:
.... sign = "-" * negative
.... val_digits = []
.... while val:
.... val, digit = divmod(val, base)
.... val_digits.append(digits[digit])
.... result = "".join(reversed(val_digits))
.... return sign + ("0" * (min_digits - len(result))) + result
....
Py> show_base(10, 2)
'1010'
Py> show_base(-10, 2)
'-1010'
Py> show_base(10, 2, 8)
'00001010'
Py> show_base(-10, 2, 8)
'-00001010'
Py> show_base(10, 2, 8, complement=True)
'00001010'
Py> show_base(-10, 2, 8, complement=True)
'11110110'
Py> show_base(10, 16, 2, complement=True)
'0A'
Py> show_base(-10, 16, 2, complement=True)
'F6'
Py> show_base(127, 16, 2, complement=True)
'7F'
Py> show_base(-127, 16, 2, complement=True)
'81'
Py> show_base(255, 16, 2, complement=True)
'FF'
Py> show_base(-255, 16, 2, complement=True)
'01'
Py> show_base(256, 16, 2, complement=True)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 10, in show_base
ValueError: Value out of range for complemented format
Py> show_base(-256, 16, 2, complement=True)
'00'
Py>

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #8
Dan Bishop wrote:
def itoa(n, base):
assert*2*<=*base*<=*16


Why have the restriction base <= 16?**int()*allows*up*to*36.**All*you
need to do is

BASE36_DIGITS = string.digits + string.lowercase


For no other reason than carelessness. I have not yet seen anything beyond
base-16 in the wild.

By the way, does anyone know the Greek name for 36?

Peter
Jul 18 '05 #9
Nick Coghlan wrote:
Huh - you remind me that I forgot to put the "show_base" Bengt and I came
up with into the ASPN cookbook. . .

Py> def show_base(val, base, min_digits=1, complement=False,
...***************digits="0123456789ABCDEFGHIJKLMN OPQRSTUVWXYZ"):
...***if*base*>*len(digits):*raise*ValueError("Not *enough*digits*for
base") ...***negative*=*val*<*0
...***val*=*abs(val)
...***if*complement:
...*****sign*=*""
...*****max*=*base**min_digits
...*****if*(val*>=*max)*or*(not*negative*and*val*= =*max):
...*******raise*ValueError("Value*out*of*range*for *complemented*format")
...*****if*negative:
...*******val*=*(max*-*val)
...***else:
...*****sign*=*"-"***negative
...***val_digits*=*[]
...***while*val:
...*****val,*digit*=*divmod(val,*base)
...*****val_digits.append(digits[digit])
...***result*=*"".join(reversed(val_digits))
...***return*sign*+*("0"***(min_digits*-*len(result)))*+*result
...


Yes, that is a bit more general. For the cookbook you might consider
factoring out the "".join() operation, thus entirely removing the upper
limit for the base (the output of the first step would be a tuple of
integers).

Peter

Jul 18 '05 #10
On Wed, 26 Jan 2005 08:58:45 +0100, rumours say that Peter Otten
<__*******@web.de> might have written:
By the way, does anyone know the Greek name for 36?


triakontahexadecimal would be a nice compromise of greek and the
"hexadecimal" convention of having six before ten -- "*ξι" ("hexi") is
six, "δ*κα" ("deka") is ten, "τριάκοντα" ("triakonta") is thirty. I
think in ancient Greek sometimes units came before tens, just like in
German (another similarity is the verb in the end of the sentence, as
Mark Twain also noted sometime in a humourous article AFAIR.)

In current Greek hexadecimal is "δεκαεξαδικόν" ("dekaexadikon").
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #11
On Wed, 26 Jan 2005 02:10:44 +0100, rumours say that "Fredrik Lundh"
<fr*****@pythonware.com> might have written:
Mike Moum wrote:
s.atoi('4',3) should result in 11

s.atoi('13',4) should result in 31

s.atoi('12',4) should result in 30

s.atoi('8',4) is legitimate, but it generates an error.

Is this a bug, or am I missing something obvious?

the function's named "atoi", not "atoitoa".


<automatic_effbot_post_translator_powered_by_pytho n>

s.itoa(4,3) should result in '11'
s.itoa(13,4) should result in '31'
s.itoa(12,4) should result in '30'
s.itoa(8,4) should result in '20'

s.atoi('4', 3) should fail
s.atoi('13', 4) should result in 7
s.atoi('12', 4) should result in 6
s.atoi('8', 4) should fail

</automatic_effbot_post_translator_powered_by_python > :)
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #12
Peter Otten wrote:
def itoa(n, base):
assert 2 <= base <= 16
if n < 0:
digits = ["-"]
n = -n
else:
digits = []
while n:
n, m = divmod(n, base)
digits.append(string.hexdigits[m])
digits.reverse()
return "".join(digits)


This is junk, sorry. Doesn't handle n<=0 correctly (at least).

Peter

Jul 18 '05 #13
Christos TZOTZIOY Georgiou wrote:
On Wed, 26 Jan 2005 08:58:45 +0100, rumours say that Peter Otten
<__*******@web.de> might have written:
By the way, does anyone know the Greek name for 36?


triakontahexadecimal would be a nice compromise of greek and the
"hexadecimal" convention of having six before ten -- "???" ("hexi") is
six, "????" ("deka") is ten, "?????????" ("triakonta") is thirty. I
think in ancient Greek sometimes units came before tens, just like in
German (another similarity is the verb in the end of the sentence, as
Mark Twain also noted sometime in a humourous article AFAIR.)

In current Greek hexadecimal is "????????????" ("dekaexadikon").


The Latin part escaped me. Now we need unicode names in Python, and the fun
can really begin.

I had you in mind with my question, thank you.

Peter

Jul 18 '05 #14
Christos TZOTZIOY Georgiou wrote:
the function's named "atoi", not "atoitoa".


<automatic_effbot_post_translator_powered_by_pytho n>


cool. can I have a copy of your script?

reminds me that I have a few patches in the inqueue. I wonder
what this one does? ;-)

hmm ;-) guess I can tune that later ;-) and what about that other
patch? ;-) let's see ;-) patch, checkout, reload File "effbot.py", line 29238
<<<<<<< .mine
^
IndentationError: expected an indented block

Jul 18 '05 #15
On Wed, 26 Jan 2005 13:23:42 +0100, rumours say that "Fredrik Lundh"
<fr*****@pythonware.com> might have written:
Christos TZOTZIOY Georgiou wrote:
the function's named "atoi", not "atoitoa".
<automatic_effbot_post_translator_powered_by_pytho n>


[Fredrik] [0]cool. can I have a copy of your script?
I hereby declare my script in perpetual alpha-testing stage, and
therefore won't be making it public, since I intend to make money out of
this [1] collecting all translations in a book called "The effbot's
guide to pythonology" [2].
reminds me that I have a few patches in the inqueue. I wonder
what this one does? ;-) hmm ;-) guess I can tune that later ;-) and what about that other
patch? ;-) let's see ;-) patch, checkout, reload File "effbot.py", line 29238
<<<<<<< .mine
^
IndentationError: expected an indented block


You're messing with the time machine again, right? Your patch is
probably for nightly build 20071202032501 . At the moment, most of the
script logic (and bugs :) is concentrated in line 2:

what_to_print = raw_input("Translation of /F's single line reply? ")
[0] got it right this time

[1] Ska vi dela femtio-femtio?

[2] which book will help you improve your own python use, hopefully :)
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #16
On Wed, 26 Jan 2005 12:26:59 +0100, rumours say that Peter Otten
<__*******@web.de> might have written:
In current Greek hexadecimal is "????????????" ("dekaexadikon").


The Latin part escaped me.


By Latin I suppose you jokingly mean the Greek parts... :)

Just in case it didn't show up correctly in your ng/mail client, it does
on groups.google.com (the post was in UTF-8, dammit! --excuse my romance
language)

message link (long URL):
<URL:http://groups-beta.google.com/group/comp.lang.python/msg/b20fc159a4f0e14a>
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #17
Christos TZOTZIOY Georgiou wrote:
You're messing with the time machine again, right?
no, it was a subversion pilot error, this time. but now that you remind me,
I have to say that this

http://mail.python.org/pipermail/pyt...ry/030720.html

is a bit scary. I wonder from where I was posting that?
[1] Ska vi dela femtio-femtio?


Jag kan tnka mig 60-40 om du str fr det praktiska.

</F>

Jul 18 '05 #18
On Wed, 26 Jan 2005 18:07:39 +0100, rumours say that "Fredrik Lundh"
<fr*****@pythonware.com> might have written:
You're messing with the time machine again, right?


no, it was a subversion pilot error, this time. but now that you remind me,
I have to say that this

http://mail.python.org/pipermail/pyt...ry/030720.html

is a bit scary. I wonder from where I was posting that?


And this post is what I was referring to with "again".
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #19
Christos TZOTZIOY Georgiou wrote:
In current Greek hexadecimal is "δεκαεξαδικόν" ("dekaexadikon").

I borrowed Guido's time machine to fix the above (hopefully) :-)
The Latin part escaped me.
By Latin I suppose you jokingly mean the Greek parts... :)


I thought it was a well-known fact that speakers of the awful German
language have absolutely no humour.

My first assumption was that hexadecimal is Greek and then I modified that
to a Greek/Latin combo "*ξαdecimal".
Just in case it didn't show up correctly in your ng/mail client, it does
on groups.google.com (the post was in UTF-8, dammit! --excuse my romance
language)


It did show up correctly, but was garbled in the response through technical
incompetence of the poster.

Peter
Jul 18 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: ken | last post by:
I've been looking for a solution to a string to long conversion problem that I've run into >>> x = 'e10ea210' >>> print x e10ea210 >>> y=long(x) Traceback (most recent call last): File...
3
by: steve morin | last post by:
http://www.python.org/doc/2.4.1/lib/node110.html These methods are being deprecated. What are they being replaced with? Does anyone know? Steve
4
by: Sharon | last post by:
hi all what are the reverse functions of atof( ), atoi( ) and atol( ) ? I want to change sth to string thx!
4
by: Ross | last post by:
Anyone have some code to help me understand how I can convert a given hex string, say "0009dbaa00004c00000000fb82ca621c," into a struct of this form: struct uniqueid { ulong32_t word1;...
15
by: Anonymousgoogledeja | last post by:
Hi all, since the function atof, atoi, _atoi64, atol returned value are Return Values Each function returns the double, int, __int64 or long value produced by interpreting the input...
13
by: Freaker85 | last post by:
Hello, I am new at programming in C and I am searching a manner to parse a string into an integer. I know how to do it in Java, but that doesn't work in C ;o) I searched the internet but I...
11
by: shanmugaster | last post by:
Hi, I have a string array which may contain 5 digit values or NULL or just blank spaces. I should print the value of array as an integer. that is it should print 0 when it encounters NULL and...
13
by: pkirk25 | last post by:
I have a string with format "0|first_name|last_name|..." which i can split to a vector<stringby the "|" token. At the moment to get the row number I'm using size_t row_number =...
1
by: migurus | last post by:
I see that atof and strtod both recognize "INF", or "+INF", or "-INF" as special case and return accordingly infinite value. But atoi and strtol do not know about this special case - why? Is there...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.