# Interesting float/int casting in Python

25 April 2006   21 comments   Python

Mind that age!

This blog post is 14 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, List,List,List,List
#--------------------------------------
f=open('temp.txt','w')
f.write(List)
f.close()
#--code ends-----------------------------

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

Regards
Nakul

Peter Bengtsson

Replace
f.write(List)
with
f.write(str(List))

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

Anonymous

Oh my Lordy! I started decoding this for you but seriously gave up. Such flow bad, such syntax no good

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!

Anonymous

Pretty poor question but here is the answer:

def replace():
while True:
try:
a = input(“Please enter a decimal or whole number”)
float(a)
print(“True”)
except ValueError:
print(“False”)

replace()

Ben davidson

Enjoy and happy coding 😃

Ben davidson

Oh don’t forget break haha 🤣 otherwise constant loop yo. Be looping for dayzzzzzzzzz

Your email will never ever be published