Skip to content
VLSI Mentor

Python Part I · Module 2 · Variables and Data Types

Whole Numbers and Decimals

Python has two number types you will use constantly, and the difference between them is not about size. It is about whether the value can have a fractional part. Counts of things — errors found, tests run, seeds — are whole numbers. Measured quantities — a runtime in seconds, a clock period, a voltage — generally are not. This chapter establishes both, shows how Python decides which one you have created, and answers the question every beginner asks within about five minutes of meeting them, which is why dividing ten by four gives 2.5 when both of the numbers involved were whole. It closes with the one genuinely surprising thing about decimal arithmetic, kept short and stated accurately, because meeting it by accident in a report is worse.

Foundation9 min readPythonPart IFundamentalsNumbersintfloat

Part I · Module 2 · Chapter 2.6 · Whole Numbers and Decimals

1. Two Kinds of Number

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
error_count = 3
runtime_s = 182.4

print(error_count)
print(runtime_s)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
3
182.4

3 is a whole number. Python calls this type int, short for integer.

182.4 has a fractional part. Python calls this type float, short for floating-point.

The everyday guide is straightforward:

  • int for things you count. Errors found, tests run, seeds, retries. You cannot have 3.5 errors.
  • float for things you measure. Runtime, frequency, voltage, slack. A measurement is rarely exactly whole.

2. How Python Decides Which You Get

This is the part that is easy to state wrongly, so it is worth being exact.

It is not the size of the number. It is not whether the value happens to be whole. It is how you write it.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a = 5
b = 5.0

print(a)
print(b)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
5
5.0

5 and 5.0 are the same quantity. They are not the same value to Python: a is an int, b is a float. The decimal point in the source is what creates a float, whether or not there is anything after it.

Notice the output confirms it — b printed as 5.0, not 5. Python is telling you which type it has.

3. Why 10 / 4 Is 2.5

Here is the question everyone asks.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(10 / 4)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
2.5

Both 10 and 4 are whole numbers, so why is the answer not whole?

Because / in Python always produces a float. It is division in the ordinary arithmetic sense, and ordinary arithmetic on whole numbers frequently produces a fraction. Python does not throw the fraction away.

This is true even when the result divides exactly:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(10 / 5)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
2.0

2.0, not 2. The division produced a float, and it printed as one. That trailing .0 is Python telling you the type, and it is not a mistake.

4. Whole Numbers Have No Practical Limit

Worth knowing, because it differs from most languages an engineer will have met.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
big = 99999999999999999999999999
print(big)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
99999999999999999999999999

There is no 32-bit or 64-bit ceiling on a Python int. It grows as needed, limited only by available memory.

If you have written C or SystemVerilog, this is a genuine difference: there is no wraparound, no overflow, and no width to declare. A counter cannot silently roll over to zero.

Floats are different — they do have limits and a fixed precision, which is §5.

5. The One Surprise Worth Knowing

Try this:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(0.1 + 0.2)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
0.30000000000000004

That is not a bug in Python. It is not a bug at all.

Floats store values in binary, and some perfectly ordinary decimal fractions — 0.1 among them — have no exact binary representation, in the same way that one third has no exact decimal representation. The stored value is extremely close but not exact, and occasionally the difference becomes visible.

Every language using the same floating-point representation behaves identically. C does this. SystemVerilog's real does this.

What this means in practice, for now:

  • For counting, use int. There is no imprecision there at all.
  • For measured quantities, float is correct and the imprecision is far below anything you would care about.
  • Do not be alarmed when a report shows 182.43999999999997 instead of 182.44. Nothing is broken; the value is simply being printed in full.

6. Which to Use

The factTypeExample
how many errors were foundinterror_count = 3
which seed was usedintseed = 4210
how many tests raninttotal_tests = 600
how long it took, in secondsfloatruntime_s = 182.4
clock frequency in MHzfloatclock_mhz = 500.0
supply voltagefloatvoltage = 0.8

clock_mhz = 500.0 is worth a note. The value is whole, but frequency is a measured quantity that could reasonably be 499.8, so writing it as a float says something true about the kind of thing it is. Either would work; the float is more honest.

7. Predict, Run, Observe

Predict each line's output exactly — including any trailing .0.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(7)
print(7.0)
print(10 / 4)
print(10 / 5)
print(100)
print(1 / 3)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
7
7.0
2.5
2.0
100
0.3333333333333333

The last one is §5 again — one third cannot be written exactly, so Python shows as much as it holds. Nothing is wrong.

8. Exercise

Exercise 1 — choose the type. For each, say int or float and write an assignment with a good name: (a) the number of failing tests; (b) the measured slack in nanoseconds; (c) the number of seeds in a sweep; (d) a supply voltage; (e) a retry limit.

Exercise 2 — predict the trailing zero. Before running, say which of these print with a .0 and which do not:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(6 / 3)
print(6)
print(6.0)
print(9 / 2)

Exercise 3 — the same quantity, two types. Write two names, one holding 500 and one holding 500.0, and print both. They represent the same quantity. Describe in one sentence what the output tells you that the values alone do not.

Exercise 4 — explain the surprise. A colleague reports that Python "got the arithmetic wrong" because 0.1 + 0.2 did not give 0.3. Answer them in two sentences, without using the word "bug", and say where the fix belongs.

9. Summary

  • int is for whole numbers, float for numbers with a fractional part.
  • How you write the value decides the type, not its size and not whether it happens to be whole. 5 is an int; 5.0 is a float.
  • / always produces a float, even when the division is exact — 10 / 5 is 2.0.
  • Python integers have no practical size limit. No width to declare, no overflow, no wraparound.
  • Floats are slightly imprecise for some decimal fractions, in every language that uses the same representation. 0.1 + 0.2 showing 0.30000000000000004 is correct behaviour.
  • Count with int, measure with float, and treat the number of displayed decimal places as a formatting question for Module 4.

Two number types down. The next chapter covers the third, which Python provides, almost no engineering script needs, and you should be able to recognise anyway.

Where this fits

Part of the Python curriculum.