Python Type Casting and Floating Point Accuracy
The second half of objective 1.4: converting between types. `int()`, `float()`, `str()` and `bool()` are four functions with a small number of sharp edges - `int("3.5")` raises where `int(3.5)` does not, and `int()` truncates where `round()` does something stranger. Float accuracy is the other half: `0.1 + 0.2` is not `0.3`, and the exam knows it.
Language Fundamentals Guide 8 of 26 Beginner
- Python3.14.4
- OSUbuntu 26.04 LTS
- pip25.1.1
- TimeAbout 16 min
- Reviewed23 August 2026
Written against the versions above. Written against **Python 3.14**. The rounding behaviour here has been the same since Python 3.0 and is a genuine Python 2 to 3 change: Python 2's `round(2.5)` was 3. Anything showing 3 is Python 2 material.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| RUNNER01 | 192.168.0.27 | Ubuntu 26.04 LTS | Python 3.14.4 - the only machine this path needs | 2 Core | 4 GB | 50 GB |
Before you start
- guide 7 - the first half of objective 1.4.
- Nothing else.
-
The four conversion functions
int(),float(),str()andbool()are the conversions the syllabus names. Each takes almost anything and produces its own type - and each has rules worth knowing exactly.Ten conversions below.
repr()is used on thestr()results so you can see that they really are strings.bash Example session cat > ~/py/casts.py <<'PY'print("int(3.9) =", int(3.9))print("int(-3.9) =", int(-3.9))print("int('42') =", int("42"))print("int(' 42 ') =", int(" 42 "))print("int(True) =", int(True))print("float('3.14') =", float("3.14"))print("float(3) =", float(3))print("float('1e3') =", float("1e3"))print("str(3.0) =", repr(str(3.0)))print("str(True) =", repr(str(True)))PYpython3 ~/py/casts.pyint(3.9) = 3int(-3.9) = -3int('42') = 42int(' 42 ') = 42int(True) = 1float('3.14') = 3.14float(3) = 3.0float('1e3') = 1000.0str(3.0) = '3.0'str(True) = 'True'Expected result3 and -3 from the floats, 42 twice, and
'3.0'in quotes.Success conditionYou can predict the value and type of any of these conversions.
-
What the conversions refuse, and with which exception
The failures are as examinable as the successes, and they are all
ValueError- the type was acceptable, the *value* was not.The first one is the trap:
int()will not read a decimal point out of a string, even though it happily truncates a float.bash Example session python3 -c 'print(int("3.5"))'Traceback (most recent call last): File "<string>", line 1, in <module> print(int("3.5")) ~~~^^^^^^^ValueError: invalid literal for int() with base 10: '3.5'[exit 1]python3 -c 'print(int(""))'Traceback (most recent call last): File "<string>", line 1, in <module> print(int("")) ~~~^^^^ValueError: invalid literal for int() with base 10: ''[exit 1]python3 -c 'print(float("abc"))'Traceback (most recent call last): File "<string>", line 1, in <module> print(float("abc")) ~~~~~^^^^^^^ValueError: could not convert string to float: 'abc'[exit 1]python3 -c 'print(int(float("3.5")))'3Expected resultThree
ValueErrors, then3from the two-step conversion.Success conditionYou can name the exception and the fix for each refusal.
-
Truthiness, in full
bool()never raises - every object in Python has a truth value. The rule is short: zero, empty, andNoneare false; everything else is true.Twelve values below, including the three that catch people.
bash Example session cat > ~/py/truthy.py <<'PY'for value in (0, 1, -1, 0.0, "", "0", " ", [], [0], (), {}, None): print(repr(value).ljust(6), "->", bool(value))PYpython3 ~/py/truthy.py0 -> False1 -> True-1 -> True0.0 -> False'' -> False'0' -> True' ' -> True[] -> False[0] -> True() -> False{} -> FalseNone -> FalseExpected resultFalse for
0,0.0,'',[],(),{}andNone; True for everything else including'0'and[0].Success conditionYou can state the truth value of any object without testing it.
-
Floats do not hold the number you wrote
A
floatis a binary fraction with fixed precision, and most decimal fractions cannot be represented in it exactly.0.1is not really 0.1; it is the nearest binary approximation.That is not a Python bug and not specific to Python. It is the IEEE-754 format that essentially every language uses.
bash Example session cat > ~/py/floats.py <<'PY'print(0.1 + 0.2)print(0.1 + 0.2 == 0.3)print(f"{0.1 + 0.2:.20f}")print(abs((0.1 + 0.2) - 0.3) < 1e-9)PYpython3 ~/py/floats.py0.30000000000000004False0.30000000000000004441TrueExpected result
0.30000000000000004, thenFalse, then twenty decimal places of the truth, thenTrue.Success conditionYou know why an equality test on floats is unsafe and what to do instead.
-
round() does not round the way you were taught
round()uses banker's rounding: a value exactly halfway goes to the nearest *even* number, not always up. And a value that merely looks halfway may not be halfway at all, because of the previous step.Five results, and at least two of them will not be what you expect.
bash Example session cat > ~/py/rounding.py <<'PY'print("round(2.5) =", round(2.5))print("round(3.5) =", round(3.5))print("round(-2.5) =", round(-2.5))print("round(2.675, 2) =", round(2.675, 2))print("int(2.9) =", int(2.9))PYpython3 ~/py/rounding.pyround(2.5) = 2round(3.5) = 4round(-2.5) = -2round(2.675, 2) = 2.67int(2.9) = 2Expected result
round(2.5)is 2,round(3.5)is 4,round(-2.5)is -2,round(2.675, 2)is 2.67,int(2.9)is 2.Success conditionYou can explain both surprises, and they have different causes.
-
What the exam does with this objective
The conversion half of 1.4 produces a small, stable set of questions:
"What does
int("3.5")do?" - raisesValueError."What is
bool('0')?" - True."Is
0.1 + 0.2 == 0.3?" - False."What is
round(2.5)?" - 2."What is
int(-3.9)?" - -3, truncated, not -4."What type is
str(3.0)?" -str, and its value is'3.0'.The three-way distinction between
int(),//andround()is the single thing most worth having straight, because a question can use any of the three on the same number and get three different answers.guide 9 finishes block 1 with console I/O, and contains one more trap of the same family.
bash rm -f ~/py/casts.py ~/py/truthy.py ~/py/floats.py ~/py/rounding.py && ls -A ~/pyExpected resultAn empty scratch directory.
Success conditionYou can convert, and you know what conversion refuses to do.
Troubleshooting
ValueError: invalid literal for int() with base 10: '3.5'.Why:
int()parses only sign and digits from a string. A decimal point is not a digit.Fix:
int(float("3.5"))- convert to float first, then truncate. Note this truncates rather than rounds.ValueError: invalid literal for int() with base 10: ''.Why: An empty string, usually from an
input()where the user pressed Enter.Fix:Check before converting:
if text.strip(): value = int(text). Or wrap it intry/except ValueError- see guide 24.A total that should be 0.3 prints as 0.30000000000000004.
Why: Binary floating point cannot represent most decimal fractions exactly.
Fix:Never compare floats with
==. Usemath.isclose(a, b)orabs(a - b) < 1e-9. For money usedecimal.Decimal, which neither exam examines but which is the right answer in real code.round(2.5)gives 2 and a spreadsheet gives 3.Why: Python 3 rounds exact halves to the nearest even number - banker's rounding.
Fix:Nothing to fix. If you need half-up,
math.floor(x + 0.5)does it, with the usual float caveats. The exam expects the banker's answer.bool("False")is True.Why:
bool()on a string tests emptiness, not content."False"is five characters.Fix:Compare explicitly:
text.lower() == "true". There is no built-in that parses a boolean out of a string.