Babylonian sexagesimal numbers.
Extant Babylonian mathematics was written on clay tablets as far back as 1900 BC, so it is nearly contemporaneous with the papyrus rolls of the Egyptians. They used a positional system of base sixty. There was no symbol for zero and the other 59 digits were additive combinations of two marks easily made with a stylus. Often no space was left between the digits, so the actual number repesented had to be figured out from the context.
Fractions
The babylonian were more sophisticated than the Egyptians in their use of fraction. They did not have a sexagesmal point but they did write sexagesimal fractional numbers. So for example, 3 and a 1/2 was written 3 30, 27 and a 1/3 was written 27 20, and so forth. It was up to the reader to determine from context the position of the sexagesimal point. We can convert integers to base 60 using the convert procedure in Maple.
> convert(123,base,60);
The sexagesimal digits are returned in a list ordered from left to right in increasing significance. Thus 123 is 3 + 2*60. Convert doesn't work directly on decimal numbers, but we can work up a definition for a word that will handle these.
> b := 123.435;
> convert(b,base,60);
Error, (in convert/base) convert/base uses a 3rd argument, beta, which is missing
> x := trunc(b);
> x :=convert(x,base,60);
In order to convert the fractional part of b to base 60, we take the fractional part of b, call it y and repeatedly strip off the integer part of 60*y.
> y :=frac(b);
>
fpart := NULL;
while (y <> 0 and nops([fpart]) < Digits) do
fpart:= fpart,trunc(60*y);
y := frac(60*y); od;
> 26/60.+6/60.^2;
Now this algorithm is coded into the word dectosexa defined below.
>
dectosexa := proc(x)
local ipart, fpart,n,i,y;
ipart := convert(trunc(x),base,60);
y := (x-trunc(x));
fpart := NULL;
while (y <> 0 and nops([fpart]) < Digits) do
fpart:= fpart,trunc(60*y);
y := frac(60*y); od;
fpart := [fpart]; [seq(ipart[-i],i=1..nops(ipart)),`;`,
seq(fpart[i],i=1..nops(fpart))]
end:
Check the definition on some extreme cases:
> dectosexa(000001);
> Digits := 13; dectosexa(2^64+(1/60)^13);
> dectosexa(0);
> dectosexa(1.000000001);
> dectosexa(000.400000);
> 24./60;
Here is the complementary word: converting from sexagesimal representation to decimal. This makes it easier to check the veracity of dectosexa.
>
sexatodec := proc(l)
local ipart,fpart,i,j,digit,num;
for i from 1 to nops(l)
while( not (whattype(l[i]) = symbol)) do 1 od;
if i > nops(l) then i := nops(l) fi;
num := 0;
for j from 1 to i-1 do
num := num+60^(j-1)*l[i-j] od;
for j from i+1 to nops(l) do
num := num+l[j]/60^(j-i) od;
(num);
end:
> num:=dectosexa(10.213);
> evalf( sd(num));
> alias(sd=sexatodec,ds=dectosexa);
>
sa := proc(l1,l2)
dectosexa(sd(l1)+sd(l2)); end;
> sa(ds(61),ds(1/60+1/60^2+1/60^3+1/60^4));
We can use the ampersand operation to define various infix operations on sexagesimal fractions.
> `&sa` := (x,y)-> sa(x,y);
> [2,3,`:`,3] &sa [1,1];
>
`&sm` := proc(x,y) options operator;
ds(sd(x)*sd(y)) end;
> [3,12,59,`;`,43] &sm [22,9,15,`;`,45,31];
>
`&se` := proc(x,n) options operator;
ds(sd(x)^n) end;
> [32,19,`;`] &se 2;
>
`&sdiv` := proc(x,y) options operator;
ds( sd(x)/sd(y)) end;
> ds(2) &sdiv ds(27);
Problems
1. The Babylonians made tables of reciprocals handy for computation purposes. They avoided the nonterminating sexagesimal fractions. Use the sexagesimal division operation &sdiv to construct a table of the reciprocals of the integers from 2 to 81. Which of the fractions are terminating fractions?
2. Why would the Babylonians come up with a base 60 numeration system?
3. Convert your social security number to sexagesimal. Factor it into primes and convert those to sexagesimal.
Divide and average method
The Babylonian mathematicians developed a useful method for approximating the square root of a number with a sexagesimal fraction. Say is wanted. Start with an estimate . Then is bracketed between x1 and , so the average of x1 and should be a better estimate to . For example, let a = 2 and x1 = 1. The x2 would be 1.5 decimal, which is 1;30 in sexagesimal. Let's check this with our sexagesimal operations defined above.
> a := ds(2);
> x1 := ds(1);
>
x2 := (x1 &sa (a &sdiv x1)) &sdiv [2,`;`];
> evalf(sd(x2));
The nice thing about the divide and average method is that it can be repeated using the computed estimate x2 as the starting point x1. So we enter
>
x1 := x2:
x2 := (x1 &sa (a &sdiv x1)) &sdiv [2,`;`];
> evalf(sd(x2));
Problems
1. A 1 place sexagesimal will convert to a 1 or 2 place decimal number. Going the other way, a 2 place decimal converts to a 1 or 2 place sexagesimal number. Suppose you have an n place sexagesimal numbers. What are the lower and upper bounds on the number of places needed to represent the number in decimal form? Work out the answer to the same question going the other way.
2. The Babylonians prepared tables of square roots for use in solving quadratic equations. Use the divide and average method to make a table of square roots of the first 20 positive integers which is accurate to 5 places.
3. Newton's method for finding an improved approximate solution to an equation f(x) = a, where a is a given number and f is a given differentiable function, is , where x1 is an approximate solution to the equation. Show that Newton's method is the divide and average method for an appropriately chosen function f.