?he 'REALS''Page %'
?fo 'Steven Hardy'- % -'2nd August, 1977'
.de bb
.sp
.ti 0
.ce
------------------------------
.sp
.tp 10
..
.mh
Real Numbers
------------
.hm
.sp2
This handout describes so-called 'real numbers', that is
numbers with decimal points in them. For example, the following
are all real numbers:
 	: 3.42, 1.07, 0.003, -126.237
.br
whilst the following are 'integers':
 	: 3, 1, 0, -126
.br
.sp
This handout is not easy to follow - do not read it unless
you
.ul
really
want to and
.ul
are sure
you won't be discouraged by it.
.sp
I can only guess why the name 'real number' was chosen - perhaps
because they are useful when measuring 'real' things like height
or weight. Whatever the etymology of the term, the POP11
system is in no doubt:
 	: DATAWORD(1.0) =>
 	** REAL
 	: DATAWORD(1) =>
 	** INTEGER
.sp
The most important thing to remember about real numbers is that
they are
.ul
inherently imprecise so that no two real numbers will ever be "=",
for example:
 	: IF	1.0 + 1.0 = 2.0
 	: THEN	"YES" =>
 	: ELSE	"NO" =>
 	: CLOSE;
 	** NO
.br
This is
partly because the computer cannot really cope with decimal
numbers and tends to get its sums slightly wrong, so that 1.0 + 1.0
might work out as 1.99999 (or perhaps 2.00001). So never
write:
 	: IF NUM = 0.0 THEN ...
.br
Instead write:
 	: IF NUM < 0.00001 THEN ...
.br
The situation is so bad that the computer cant even read in (or
print out) real numbers properly, so that even 0.0 = 0.0 is false!
If you want to see if two real numbers, say X and Y are the 'same'
write something like
 	: IF ABS(X-Y) < 0.00001	THEN ...
.br
N.B. ABS (short for absolute 'value') always returns a positive
number (more precisely a non-negative number). Sometimes
EQUAL
will work 'properly' on real numbers, for example
EQUAL(1.0,1.0)
is
TRUE
(we recall that X=Y is
.ul
always
FALSE
if (the values of) X and Y are real numbers.)
.br
.tp12
An example:
the following functions compute the 'mean', (or average) of
a list of numbers:
.tp10
 	: FUNCTION SUM(LIST);
 	:	IF	LIST = NIL
 	:	THEN	0
 	:	ELSE	HD(LIST) + SUM(TL(LIST))
 	:	CLOSE
 	: END;
 	: FUNCTION MEAN(LIST);
 	:	SUM(LIST) / LENGTH(LIST)
 	: END;
 	: MEAN([1 2 3 4]) =>
 	** 2.5
.br
The arithmetic operations + - and * will return an integer only if both their arguments
are integral.
If given two integers the division operator / returns a real number
if there would be a remainder, that is:
 	: 8 / 4 =>
 	** 2 (an integer)
 	: 9 / 4 =>
 	** 2.25 (a real)
.br
.bb
.ul
Exercises
.pg
Write a function called 
SQUARE,
which takes as argument a list of numbers, for example:
 	: SQUARE([1 2 3 4]) =>
.br
and returns a list of the squares of the number, that is
 	** [1 4 9 16]
.br
Use this function to write
MEANSQ,
a function to compute the average of the squares of a set of
numbers, that is
 	: MEANSQ([1 2 3 4]) =>
 	** 7.5
.br
Notice, this is
.ul
not
the same as
 	: MEAN([1 2 3 4]) * MEAN([1 2 3 4]) =>
.br
which is
 	** 6.25
.bb
.pg
Real numbers are sometimes called 'floating point numbers'. This is
because their accuracy is measured in terms of 'number of
significant digits' rather than absolute value. In POP11, the first
six digits of a real number (excluding leading zeroes) are significant
no matter where the decimal point is. The decimal point can 'float',
multiplying a real number by, say, ten doesn't affect its accuracy.
An implication of this is that
 	: 123456.0 + 654321.0 =>
 	** 777777.0
.br
is reasonable, as is
 	: 1.23456 + 6.54321 =>
 	** 7.77777
.br
but
 	: 123456.0 + 6.54321 =>
 	** 123463.0
.br
is accurate to only, six significant figures. (The result may, as
here, be 'rounded up'.)
.sp
Beware: the POP11 system can't cope with real numbers much
above a million million nor much below a millionth of a millionth -
I don't think this much of a restriction.
.sp
.ce
--------------------------
.sp
The following functions are (or will be) available for manipulating
real numbers.
.br
.ti-5
.sp
SQRT
square root.
.sp
.ti-5
INTOF    
Given a real number this function returns the integer part, for example:
 	: INTOF(3.6) =>
 	**  3
.br
N.B., if X is negative then
 	: INTOF(X) = -INTOF(-X)
so
 	: INTOF(-3.6) =>
 	** -3
.br
.sp
.ti-5
ROUND    
Given a real number this function returns the 
.ul
closest
integer,
for example:
 	: ROUND(3.6) =>
 	** 4
.br
.sp
.ti-5
REALOF    
Given an integer this function returns the corresponding real
number, for example:
 	: REALOF(3) =>
 	** 3.0
.br
If X is an integer then
 	: X = INTOF(REALOF(X))
.bb
.ul
More Exercises

Suppose you know that a group of workers earn the following
sums of money a week:
 	: [112.34 96.40 87.05 103.56 99.39]
.br
(rather a small sample I agree). Extrapolating from this sample
how probable do you consider it that
.ul
the
average worker earns, say, 92.07 a week? Write a function
which compares this probability.
.sp
Suppose, further, that the same group of workers is
paid
(as opposed to 
earns)
 	: [37.24 83.00 130.45 65.75 82.00]
.br
(People don't always get paid what they've earned.)
Write a function to guess what someone is paid given what
they earn, also compute a measure by 'confidence' in this value.
.br
Hint: Think of the problem in terms of fitting a curve to
points on a graph. As a first approximation try fitting a
straight line to the points. The above figures aren't too good
for this, try instead a height/weight table or something similar.
