標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第556回]

●ATN()関数

[第548回]から[第550回]で三角関数について説明をしましたが、もうひとつ紹介するのを忘れておりました。
ATN()関数です。
一般にarctanとかtan-1と表現します。アークタンジェント(逆正接)です。
普通の三角関数は角度(またはラジアン)を与えて、その角に対する値(三角比)を求めるものですが、tan-1はこれとは逆にtanによって求められた値から逆にもとの角を導き出すものです。
三角関数に対して逆三角関数といいます。

EXCELにはASIN()やACOS()もありますが、Z80BASICではtan-1だけがあります。sin-1やcos-1はありません。

tanの逆関数ですからTAN()と一緒に使ってみます。

>list
     5 ON ERROR GOTO 70
    10 FOR A=0 TO 90 STEP 5
    20 T=SID(A)/COD(A)
    30 RAT=ATN(T)
    35 DAT=RAT/PI*180
    40 PRINT A,T,DAT
    50 NEXT A
    55 PRINT "end"
    60 STOP 
    70 PRINT A,"***","***"
    80 RESUME 50
>run
0            0            0
5            0.874887E-1  5
10           0.176327     10
15           0.267949     15
20           0.36397      20
25           0.466308     25
30           0.57735      30
35           0.700207     35
40           0.839099     40
45           1            45
50           1.19175      50
55           1.42815      55
60           1.73205      60
65           2.14451      65
70           2.74748      70
75           3.73205      75
80           5.67128      80
85           11.43        85
90           ***          ***
end


break in 60

プログラムについては少し説明が必要かもしれません。
FOR NEXTを使って0度〜90度の間のtanを5度きざみで求めるとともに、その求めた値をATN()関数に入れて、もとの度数を求める、ということをさせています。
ところがZ80BASICでは、TAN()関数はラジアンのみで度に対するtanはありません。
度をラジアンに直してからTAN()に与えてもよいのですが、ここではtan=sin/cosですから、度で計算するSID()とCOD()を使って、SID()/COD()を計算して、その度のときのtanを求めています。

ところで、ATN()も計算した結果はラジアンになります。
これは仕方がありませんから、180/πを掛けて度に変換しています。
90度のtanは計算できませんから、on error goto文で処理しています。

●renコマンド

renコマンド(renumber)は[第550回]で少し説明をしています。
行番号を付け直すコマンドです。
行番号は行の先頭に置かれていますが、それ以外にgoto文やresume文などでも使われています。
renコマンドはそのgoto文やresume文の行番号も正しく付け直します。
今回のサンプルプログラムはちょうどgoto文、resume文を使っていますから、renコマンドの参考例としてrenコマンドを使ってみました。
renコマンドでさきほどのプログラムの行番号が行の先頭の番号だけではなくて、goto文、resume文も含めて付け直されていることに注目してください。

>ren
>list
    10 ON ERROR GOTO 100
    20 FOR A=0 TO 90 STEP 5
    30 T=SID(A)/COD(A)
    40 RAT=ATN(T)
    50 DAT=RAT/PI*180
    60 PRINT A,T,DAT
    70 NEXT A
    80 PRINT "end"
    90 STOP 
   100 PRINT A,"***","***"
   110 RESUME 70
>run
0            0            0
5            0.874887E-1  5
10           0.176327     10
15           0.267949     15
20           0.36397      20
25           0.466308     25
30           0.57735      30
35           0.700207     35
40           0.839099     40
45           1            45
50           1.19175      50
55           1.42815      55
60           1.73205      60
65           2.14451      65
70           2.74748      70
75           3.73205      75
80           5.67128      80
85           11.43        85
90           ***          ***
end

break in 90


●ATN()関数(倍精度)

さて、ではいつものように、上のサンプルプログラムも倍精度に直して計算をさせてみましょう。

>list
    10 ON ERROR GOTO 100
    20 FOR A#=0 TO 90 STEP 5
    30 T#=SID(A#)/COD(A#)
    40 RAT#=ATN(T#)
    50 DAT#=RAT#/PI#*180
    60 PRINT A#,T#,DAT#
    70 NEXT A#
    80 PRINT "end"
    90 STOP 
   100 PRINT A#,"***","***"
   110 RESUME 70
>run
0            0            0
5            0.8748866352592399D-1     5
10           0.176326980708465         10
15           0.2679491924311227        15
20           0.3639702342662023        20
25           0.4663076581549985        25
30           0.5773502691896257        30
35           0.7002075382097097        35
40           0.83909963117728          40
45           1            45
50           1.19175359259421          50
55           1.428148006742115         55
60           1.732050807568877         60
65           2.144506920509559         65
70           2.747477419454622         70
75           3.732050807568877         74.99999999999999
80           5.671281819617712         80
85           11.43005230276134         85
90           ***          ***
end

break in 90

75度のところで誤差のためちょっとみっともない表示になってしまいました。
それと0、45、90度のときの表示が他の表示と揃っていません。
その2点を直して再実行してみました。

>list
    10 ON ERROR GOTO 120
    20 FOR A#=0 TO 90 STEP 5
    30 T#=SID(A#)/COD(A#)
    40 RAT#=ATN(T#)
    50 DAT#=RAT#/PI#*180
    60 IF (A#=0)+(A#=45)PRINT A#,T#," ",DAT#:GOTO 90
    70 IF A#=75 PRINT A#,T#,DAT#+0.00000000000001:GOTO 90
    80 PRINT A#,T#,DAT#
    90 NEXT A#
   100 PRINT "end"
   110 STOP 
   120 PRINT A#,"***"," ","***"
   130 RESUME 90
>run
0            0                         0
5            0.8748866352592399D-1     5
10           0.176326980708465         10
15           0.2679491924311227        15
20           0.3639702342662023        20
25           0.4663076581549985        25
30           0.5773502691896257        30
35           0.7002075382097097        35
40           0.83909963117728          40
45           1                         45
50           1.19175359259421          50
55           1.428148006742115         55
60           1.732050807568877         60
65           2.144506920509559         65
70           2.747477419454622         70
75           3.732050807568877         75
80           5.671281819617712         80
85           11.43005230276134         85
90           ***                       ***
end

break in 110

行番号60のIF文は条件式がORになっています。
Z80BASICのIF文では条件式のORは、行番号60のように、+記号を使って、
IF (A#=0)+(A#=45)
と表現します。
ANDの場合は、*記号を使って条件式をつなぎます。
IF (A=0)*(B<0)
のように使います。

行番号70では、DAT#+0.1D−13というように入力したのですが、リスト表示ルーチンが、上で表示されたように表示してしまいます。
間違いではありませんから、このままにしておくことにしますが、リスト表示ルーチンにちょいとクセがあるようです。

2010.7.18upload

前へ
次へ
ホームページトップへ戻る