fortran66のブログ

fortran について書きます。

バビロニアの数表

ブルーバックスの芹沢正三著『素数入門』6-5節に、古代バビロニア三角関数表が載っているので、それを計算してみます。

数学の表現形式として、古代エジプト文明は測量術から幾何学を、古代メソポタミア文明は天体観測から整数論を好んだようです。古代ギリシア文明は非常に遅れていましたが、先進的東方諸国に学び、結果だけを頂戴したようです。ピタゴラスバビロニア式の整数論を採って数秘術的な整数崇拝をしたと伝えられています。もっとも、その弟子が正方形の対角線が整数比で表せないことを証明し、ギリシア世界では幾何学が主流になったようです。表現形式として幾何学のほうが整数論より勝るという理由によるようです。

古代メソポタミア人は天気のよい土地柄か、夜毎に天体観測に没頭しては天体の周期運動を観測し、ついでに周期の整数比や整数値そのものに、妙な思い入れを投影して数崇拝をしたようです。彼らは計算をもっぱら粘土板上の数表を参照することで行ないましたが、これは砂の上に幾何学図形を描いた古代ギリシア式数学とは大きく異なります。現在ピタゴラスの定理と呼ばれているものにあたる数値を記した粘土板も出土しています。

上述の『素数入門』中に、出土粘土板から得られたピタゴラスの定理を満たす数値の表が与えられています。それを三角形として解釈すると角度がおおよそ一度刻みになっているとの記述があります。元の粘土板にはさらに対応する三角関数値が与えられているそうです。

ここでは、60進法で与えられた表を10進法に直して三角形の三辺を求め、ピタゴラスの定理が成り立っていることを確かめ、鋭角の角度を求めます。


実行結果


微妙に歯抜けしつつ、0.5 度おきだったのが途中から 1 度おきになっているようです。

Fortran ソース

MODULE m_table
IMPLICIT NONE
INTEGER, PARAMETER :: max60 = 3
TYPE :: t_base60
 INTEGER :: k(max60)
END TYPE
!
TYPE :: t_table
 TYPE(t_base60) :: column(3)
END TYPE
!
TYPE (t_table) :: claytable(15)
!
CONTAINS
!-------------------------------------
SUBROUTINE init_table()
IMPLICIT NONE
TYPE (t_table) :: unko
claytable( 1) = t_table([ t_base60([0,  2,  0]), t_base60([0,  1, 59]), t_base60([0,  2, 49]) ])
claytable( 2) = t_table([ t_base60([0, 57, 36]), t_base60([0, 56,  7]), t_base60([1, 20, 25]) ])
claytable( 3) = t_table([ t_base60([1, 20,  0]), t_base60([1, 16, 41]), t_base60([1, 50, 49]) ])
claytable( 4) = t_table([ t_base60([3, 45,  0]), t_base60([3, 31, 49]), t_base60([5,  9,  1]) ])
claytable( 5) = t_table([ t_base60([0,  1, 12]), t_base60([0,  1,  5]), t_base60([0,  1, 37]) ])
claytable( 6) = t_table([ t_base60([0,  6,  0]), t_base60([0,  5, 19]), t_base60([0,  8,  1]) ])
claytable( 7) = t_table([ t_base60([0, 45,  0]), t_base60([0, 38, 11]), t_base60([0, 59,  1]) ])
claytable( 8) = t_table([ t_base60([0, 16,  0]), t_base60([0, 13, 19]), t_base60([0, 20, 49]) ])
claytable( 9) = t_table([ t_base60([0, 10,  0]), t_base60([0,  8,  1]), t_base60([0, 12, 49]) ])
claytable(10) = t_table([ t_base60([1, 48,  0]), t_base60([1, 22, 41]), t_base60([2, 16,  1]) ])
claytable(11) = t_table([ t_base60([0,  1,  0]), t_base60([0,  0, 45]), t_base60([0,  1, 15]) ])
claytable(12) = t_table([ t_base60([0, 40,  0]), t_base60([0, 27, 59]), t_base60([0, 48, 49]) ])
claytable(13) = t_table([ t_base60([0,  4,  0]), t_base60([0,  2, 41]), t_base60([0,  4, 49]) ])
claytable(14) = t_table([ t_base60([0, 45,  0]), t_base60([0, 29, 31]), t_base60([0, 53, 49]) ])
claytable(15) = t_table([ t_base60([0,  1, 30]), t_base60([0,  0, 56]), t_base60([0,  1, 46]) ])
RETURN
END SUBROUTINE init_table
!-------------------------------------
INTEGER FUNCTION icalc60(n60)
TYPE (t_base60), INTENT(IN) :: n60
INTEGER :: i
icalc60 = 0
DO i = 1, max60
 icalc60 = icalc60 + 60**(max60 - i) * n60%k(i)
END DO
RETURN
END FUNCTION icalc60
END MODULE m_table
!=========================================
PROGRAM test
USE m_table
IMPLICIT NONE
REAL, PARAMETER :: pi = 4.0 * ATAN(1.0)
INTEGER :: i, m1, m2, m3
CALL init_table()
DO i = 1, 15
 m1 = icalc60(claytable(i)%column(1))
 m2 = icalc60(claytable(i)%column(2))
 m3 = icalc60(claytable(i)%column(3))
 PRINT '(a, i12, a, i12)', ' Check Pythagorean theorem: a^2 + b^2', m1**2 + m2**2, ': c^2', m3**2
END DO
PRINT *
DO i = 1, 15
 m1 = icalc60(claytable(i)%column(1))
 m2 = icalc60(claytable(i)%column(2))
 m3 = icalc60(claytable(i)%column(3))
 PRINT '(a, 3i12, a, f6.1)', ' a, b, c =', m1, m2, m3, ': ATAN(b/a) Angle=', ATAN2(REAL(m2), REAL(m1)) * 180.0 / pi
END DO
STOP
END PROGRAM test