# Interesting float/int casting in Python

25 April 2006   16 comments   Python

Mind That Age!

This blog post is 11 years old! Most likely, its content is outdated. Especially if it's technical.

Casting is when you convert a variable value from one type to another. This is, in Python, done with functions such as `int()` or `float()` or `str()`. A very common pattern is that you convert a number, currently as a string into a proper number.

Let me exemplify:

```>>> x = '100'
>>> y = '-90'
>>> print x + y
100-90
>>> print int(x) + int(y)
10
```

That was the `int()` function. There's also another very common one which is `float()` which does basically the same thing:

```>>> print float(x) + float(y)
10.0
```

Today I had to fix a bug might come as a surprise. Allow me to demonstrate:

```>>> x = '100.0'
>>> print float(x)
100.0
>>> print int(float(x))
100
>>> print int(x)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: invalid literal for int(): 100.0
```

As you can see, the `int()` function can convert floating point numbers to integers just fine but it can't do that and decode it from a string in one statement. A flaw in the design? No, I don't think so. It's just another design decision that you just have to learn. But, is it to explicit? Would it be that bad if the `int()` function could do both actions in one builtin sweep?

The bug I found was related to a human height input validator that looked something like this:

```def validHeight(cm):
try:
cm = int(cm)
return 100 <= cm <= 250
except ValueError:
return False

>>> validHeight(190)
True
>>> validHeight('190')
True
>>> validHeight('')
False
>>> validHeight('190.0')
False # WHAT?!
```

You see, our system saves all values like this in the database as REAL (floating point decimal values) and when you return to the Height form it prints "190.0" as the default prefilled value in the input box. In the database it's a valid and correct value. The `validHeight()` function had to be rewritten to this:

```def validHeight(cm):
try:
cm = float(cm)
return 100 <= cm <= 250
except ValueError:
return False

>>> validHeight(190)
True
>>> validHeight('190')
True
>>> validHeight('')
False
>>> validHeight('190.0')
True
```

Geez! What a long boring story this became. Just remember, `float()` is sometimes better than `int()`. In some cases you might have to use both.

Steve Holden
Of course normally you would define a function that used float() and int() along with exception handling to do exactly what you needed, just like you did with ValidHeight. The real question (no pun intended) is why you are storing them in the database as floating point numbers when you are validating them as integers. It's that discrepancy that gives rise to the problem in the first place.
Peter Bengtsson
The reason we stored them as real was because in this particular application we reuse the same sql table for storing the answers to all questions in a complex questionnaire and part of it was a slightly off-topic question about the users height and weight.
Ian Bicking
I think I saw something in the py3k list about distinguishing truncation from coercion, which is basically the problem you are having.
Anonymous
why not use:

cm = eval(cm)

or even:

cm = int(eval(cm))
Carl Friedrich Bolz
because then some mean person could give you some input like "2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** (2 ** 2)))))))))))))))))))" on the webpage, taking loads of CPU on your server. Or even worse, try to delete some files. This probably works, because the strings that are validated seem to be user-provided.
drew
"casting" usually means using an object of one type as another. In C, (char *)voidPtr doesn't convert anything, and it doesn't make a new object. It just uses voidPtr as a char*. I recommend saying 'convert' (like you did most of the time) and leaving the term 'cast' for times when an object is forced to be interpreted as something else (which isn't happening in your demos).
Peter Bengtsson
Thanks! Interesting. Cast is like when a man dresses up like a drag queen. Doesn't make him a woman.
Converting is like a man having a sex change operation then I guess.
:)
Robert
What a fantastic analogy! Thanks!
mypalmike
Casting does mean converting. In both C and Python, casting from float to int is very much a conversion. It takes the original fp number, which is generally represented internally as an IEEE 754 floating point value, and converts it to an twos completment integer representing the floor of the value. The new value has a completely different representation than the original. In other words, it is a different object.

Your example of casting pointers doesn't modify anything because a pointer is a pointer, so no underlying representation needs to be changed for the semantics of conversion to take place.
FutureNerd
Casting in C (or C++ or Java) is that (int) x syntax. It sometimes means converting, sometimes means reinterpreting the bytes, sometimes both! E.g., in C:
<pre>
char x = -1;
long y = (unsigned char) x; // y = 255
long z = (unsigned short) x; // z = 65535 (!)</pre>

The Python int(x) syntax more clearly implies "convert" to my eyes.
Nakul
Hi,
I m trying to save the values from the array to the text file in Python. when i give print command to display the array, there is no problem... but when i try to add the values from the array to the text file it is doing nothing..
How to do type casting here..
my code is.

#--code start----------------------------
print 'List values are : ', List[0], List[1],List[2],List[3],List[4]
#--------------------------------------
f=open('temp.txt','w')
f.write(List[0])
f.close()
#--code ends-----------------------------

Note:- I dont know which kind of array is this

Regards
Nakul
Peter Bengtsson
Replace
f.write(List[0])
with
f.write(str(List[0]))
Moe
Hi hows it going?
im trying to open a note pad file using python, the commands i use , load the program but when i choose which ever questionare it doesnt load it can u please let me know the problem? because i got a mid term in 5 days thnx alot the code is the following:
def IQ():
x=0
while x!=10:
score =0
myfile= open('IQ.txt', 'r')
print question
x=x+1
print"\nRight",
score+=points
else:
print"\nWrong",
print explanation
print "score:",score,"\n\n"
def Random():
x=0
while x!=10:
score =0
myfile= open('Random.txt', 'r')
print question
x=x+1
print"\nRight",
score+=points
else:
print"\nWrong",
print explanation
print "score:",score,"\n\n"

total=0
while total==0:
print "1- IQ"
print "2- Random"
choice=(raw_input("which game you wana play:"))
try:
choice=int(choice)
if choice==1:
IQ()
total=total+1
if choice==2:
Random()
total=total+1
else:
print"you should enter either 1 or 2"
total=0
except:
print "you should enter a number"
total=0
Graham Jones
Good explanation - I have just discovered to my cost that the same 'feature' exists now, and is not exactly well documented!

Thanks
CircuitDude
Thank you this little ice breaker on python casting is superb!
Gaynor Agius
Hi, I am trying to practice a little and I came across this question which I am finding hard to do.
I am still a beginner in Python so I appreciate some help and sorry if my English is not that good, it's not my primary language.

The question is as follows:

Create a function which can replace the input function and returns a float value.
If the user enters anything else besides digits and a decimal point, the input is rejected and the process loops.

To check for digits and decimal points, you can create another function which returns TRUE if the string contains only number and a decimal point, and FALSE if other characters are present.

Thank you!
Thank you for posting a comment

Your email will never ever be published

## Related posts

Previous:
Best bicycle locks 22 April 2006
Next:
Helpdeskshow - a quick review 26 April 2006
Related by Keyword:
Cope with JSONDecodeError in requests.get().json() in Python 2 and 3 16 November 2016
django-html-validator 20 October 2014
Sorting mixed type lists in Python 3 18 January 2014
Calculator in Python for dummies 17 December 2007
Comparing REAL values in PostgreSQL 07 February 2007
Related by Text:
bool is instance of int in Python 05 December 2008
cache_memoize - a pretty decent cache decorator for Django 11 September 2017
niceboolean() - converts what you say to what you mean 21 January 2005
Calculator in Python for dummies 17 December 2007
Sorting mixed type lists in Python 3 18 January 2014