munotes®

The Primitive Types, and Where They Stop

Get access to whole semester resourcesSemester Pass

Chapter Four

Syllabus topic Module 1, "Abstract Data Type: Different Data Types"

Pages 11 to 13 of 411

In one line

The primitive types are the ones the language gives you ready made, each holding a single value, and the moment a problem has many values they are not enough on their own.

The four families

Every language you will meet has these, whatever it calls them.

FamilyHoldsPythonC
Integerwhole numbersintint, long, short
Realnumbers with a fractional partfloatfloat, double
Characterone letter or symbol(a str of length 1)char
Booleantrue or falsebool_Bool

Python has no separate character type: a single letter is just a string of length one. C has no separate boolean until C99, and used integers instead, 0 for false. These differences are examinable, so the table above says both.

What a primitive can and cannot do

n = 42
r = 3.75
c = "Z"
flag = False

print("integer  :", n, type(n).__name__, "| n * 2 =", n * 2)
print("real     :", r, type(r).__name__, "| r * 2 =", r * 2)
print("character:", c, type(c).__name__, "| ord(c) =", ord(c))
print("boolean  :", flag, type(flag).__name__, "| not flag =", not flag)
print()
print("integer division 7 // 2 :", 7 // 2)
print("real division    7 / 2  :", 7 / 2)
print("0.1 + 0.2 == 0.3        :", 0.1 + 0.2 == 0.3)
print("0.1 + 0.2 is actually   :", 0.1 + 0.2)
integer  : 42 int | n * 2 = 84
real     : 3.75 float | r * 2 = 7.5
character: Z str | ord(c) = 90
boolean  : False bool | not flag = True

integer division 7 // 2 : 3
real division    7 / 2  : 3.5
0.1 + 0.2 == 0.3        : False
0.1 + 0.2 is actually   : 0.30000000000000004

0.1 + 0.2 is not 0.3, and that is not a bug. A real number is stored in a fixed number of bits, and most decimal fractions cannot be written exactly in binary any more than one third can be written exactly in decimal. So a float is an approximation, and two floats should almost never be compared with ==. Compare the difference against a small tolerance instead. This costs students marks and costs programmers money, and it is a property of the type, which is why it belongs here.

Where the limits are

Integers in most languages have a largest value. Python's do not, and it is worth seeing the difference rather than being told it:

import sys

print("Python int: no fixed maximum. 2 ** 200 =")
print(2 ** 200)
print()
print("float: largest and smallest, from the machine itself")
print("  max float :", sys.float_info.max)
print("  min normal:", sys.float_info.min)
print("  digits it can be trusted to:", sys.float_info.dig)
print()
print("what happens past the top of a float:")
big = sys.float_info.max
print("  max * 2 =", big * 2)
munotes.in11

The Primitive Types, and Where They Stop

Python int: no fixed maximum. 2 ** 200 =
1606938044258990275541962092341162602522202993782792835301376

float: largest and smallest, from the machine itself
  max float : 1.7976931348623157e+308
  min normal: 2.2250738585072014e-308
  digits it can be trusted to: 15

what happens past the top of a float:
  max * 2 = inf

A float that grows past its largest value becomes inf rather than wrapping. A C integer that grows past its largest value wraps to a negative number silently, which is the more dangerous behaviour and the reason overflow is a standard examination topic.

Where the primitives stop, and the paper begins

Here is the wall, and the whole of the rest of this book is the answer to it.

A primitive holds one value. Consider the smallest realistic problem: the marks of the students in a class.

mark1 = 78
mark2 = 65
mark3 = 91

print("average of three:", (mark1 + mark2 + mark3) / 3)
print()
print("now do it for sixty students, with sixty named variables.")
print("and then sort them.")
print("and then find the student ranked seventh.")
average of three: 78.0

now do it for sixty students, with sixty named variables.
and then sort them.
and then find the student ranked seventh.

Three problems appear at once, and none of them is about arithmetic.

You cannot write sixty variables and mean it. The program would have to be rewritten for a class of sixty one.

You cannot loop over separately named variables. A loop needs a way to say "the next one", and separate names have no next.

You cannot sort them. Sorting means moving values around by position, and a name is not a position.

What is needed is a way to hold many values under one name, reachable by position. That is the array, it is the next structure in this book, and every other structure here is a response to something the array cannot do.

Quick revision

  • The primitive types are integer, real, character and boolean; each holds a single value.
  • Python has no separate character type (a one-letter string) and its booleans are a kind of integer.
  • // is integer division, / is real division.
  • Floats are approximations: 0.1 + 0.2 is not exactly 0.3, so never compare floats with ==;

compare the difference against a tolerance.

  • Floats have a largest value and overflow to inf. Fixed width integers in C wrap silently instead.
  • Python integers have no fixed maximum.
  • A primitive holds one value. A problem with many values needs many values under one name, reachable

by position, and that is where data structures begin.

munotes.in12

The Primitive Types, and Where They Stop

Test yourself

1. Name the four primitive families and what each holds. Integer (whole numbers), real or float (numbers with a fractional part), character (one symbol), boolean (true or false).

2. Why should two floats not be compared with ==? Because a float is a binary approximation of a decimal value, so arithmetic leaves tiny errors: 0.1 + 0.2 gives 0.30000000000000004. Compare the absolute difference against a small tolerance.

3. What is the result of 7 // 2 and how does it differ from 7 / 2? 7 // 2 is 3, integer division discarding the fraction. 7 / 2 is 3.5.

4. What happens when a float exceeds its maximum, and how does a fixed width C integer differ? The float becomes inf. The C integer wraps around to a negative value with no warning, which is the more dangerous of the two.

5. Give three reasons sixty separately named variables cannot hold a class's marks. The program cannot be written for an unknown class size; a loop has no way to move to the next one; and sorting needs positions, which names do not have.

6. What property must the next structure have, that a primitive does not? It must hold many values under one name and let any of them be reached by position.

munotes.in13

The rest of this subject

These notes are cut from the University's printed syllabus. Open the syllabus itself, or the past papers, for the same subject.

Issue
Done!