第20講 n進数演算−−−引き算
第7話 引き算プログラム解説その2
を実現するプログラム主要部分再掲
Sub hz(a() As Integer, b() As Integer, c() As Integer, n As Integer)
Dim d(100) As Integer, e(100) As Integer, i As Integer, j As Integer
Dim ik1 As Integer, ik2 As Integer, mx As Integer, hn As Integer
hn = h(a(), b(), n)
If hn > 0 Then
i = 0
Do While 1
If a(i) = n Then
ik1 = i
Exit Do
End If
d(i) = a(i)
i = i + 1
Loop
i = 0
Do While 1
If b(i) = n Then
ik2 = i
Exit Do
End If
e(i) = b(i)
i = i + 1
Loop
Else
i = 0
Do While 1
If a(i) = n Then
ik1 = i
Exit Do
End If
e(i) = a(i)
i = i + 1
Loop
i = 0
Do While 1
If b(i) = n Then
ik2 = i
Exit Do
End If
d(i) = b(i)
i = i + 1
Loop
End If
mx = ik1
If mx < ik2 Then mx = ik2
i = 0
Do While 1
If i = mx Then Exit Do
Cells(6, 2 + mx - i) = d(i)
i = i + 1
Loop
i = 0
Do While 1
If i = mx Then Exit Do
Cells(7, 2 + mx - i) = e(i)
i = i + 1
Loop
For i = 0 To mx - 1
If d(i) < e(i) Then
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
End If
c(i) = d(i) - e(i)
Next
For i = mx To 0 Step -1
If c(i) > 0 Then
If hn > 0 Then
c(i + 1) = n
Else
c(i + 2) = n
c(i + 1) = n + 1
End If
Exit For
End If
Next
Cells(8, 1) = "a-b="
i = 0
Do While 1
If c(i) = n Then Exit Do
If c(i) < n Then Cells(8, 2 + mx - i) = c(i)
If c(i) = n + 1 Then Cells(8, 2 + mx - i) = " -"
i = i + 1
Loop
End Sub
参考ダウンロード添付ファイル
解説その2
前話では、
赤い囲いの表示まで解説しました。
今話はその下の引き算がいかに行われているかを解説します。
For i = 0 To mx - 1
If d(i) < e(i) Then
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
End If
c(i) = d(i) - e(i)
Next
For i = mx To 0 Step -1
If c(i) > 0 Then
If hn > 0 Then
c(i + 1) = n
Else
c(i + 2) = n
c(i + 1) = n + 1
End If
Exit For
End If
Next
が引き算のエンジンです。
For i = 0 To mx - 1
If d(i) < e(i) Then
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
End If
c(i) = d(i) - e(i)
Next
がエンジンの核心部分です。これについては後に説明します。
For i = mx To 0 Step -1
If c(i) > 0 Then
If hn > 0 Then
c(i + 1) = n
Else
c(i + 2) = n
c(i + 1) = n + 1
End If
Exit For
End If
Next
では、終わり記号nとマイナス記号"-"を表す(n+1)を刻印しています。
a≧bのときには、終わり記号nのみを書き込み、
a<bのときには、終わり記号nとマイナス記号"-"を表す(n+1)の書き込みをしています。
c(i + 2) = n
c(i + 1) = n + 1
ですから、終わり記号nの1つ手前にマイナス記号"-"を表す(n+1)を挿入しています。
シートの-の表示のために必要な処置です。
bの方がaより大きい場合には、-を表示する必要がありましたね。
さて、エンジンの核心部分である
For i = 0 To mx - 1
If d(i) < e(i) Then
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
End If
c(i) = d(i) - e(i)
Next
を解説しましょう。
を例にして説明しましょう。
すなわち、
d(0)=4,d(1)=0,d(2)=4,d(3)=0,d(4)=0,d(5)=5,d(6)=1,d(7)=0,d(8)=2,d(9)=2
e(0)=5,e(1)=4,e(2)=6,e(3)=6,e(4)=1,e(5)=4,e(6)=6,e(7)=1,e(8)=3,e(9)=0
で扱っている数は7進数です。
For i = 0 To mx - 1
の範囲は、0〜9までです。
0を含めて10個ですから、
を範囲にしています。
実際の個数を数えて下さい。
上は10桁ですよね。
If d(i) < e(i) Then
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
End If
c(i) = d(i) - e(i)
ですから、d(i) < e(i)のときには、
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
と
c(i) = d(i) - e(i)
の両方が実行され、
d(i) ≧ e(i) ときには
c(i) = d(i) - e(i)
のみが実行されます。
では、トレースしてみましょう。
i = 0 のとき、
d(0) = 4 e(0) = 5
すなわち、d(i) < e(i)で、
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
d(i) = d(i) + n
と
c(i) = d(i) - e(i)
の両方が実行されます。
For j = i + 1 To mx - 1
は
For j = 1 To 9
ですから、
1回目のループは
If d(1) > 0 Then
d(1) = d(1) - 1
Exit For
Else
d(1) = 6
End If
ですが、
d(1) = 0
ですから、Else側が実行されて
d(1) = 6
となります。
これは、一桁目の 4 - 5 を実行しようとしましたが、
4から5は引きませんので、1つ上の位である二桁目から1を借りようとしましています。
(※)
残念ながら、二桁目は財産をもっていません。
そこで、二桁目はさらに上の三桁目から1を借りことになります。
二桁目から見ると三桁目から1を借りるのは、10すなわち10進数の7を借りたことになります。
7借りたことにより、二桁目の財産は7となり、その中から1を一桁目に貸したのです。
ですから、d(1) = 6 です。
三桁目から1を借りるのは、1回目のループでではなく、2回目のループにおいてです。
二桁目の1は一桁目から見ると10すなわち10進数の7です。
一桁目の財産は7を借りたことによって4 + 7 = 11 になりますが、
これが実行されるのは、最後から2番目です。
これで一桁目の引き算は、11 - 5となり実行できて6となることになります。
If d(1) > 0 Then
d(1) = d(1) - 1
Exit For
が実行されなかったので、2回目のループに入ります。
If d(2) > 0 Then
d(2) = d(2) - 1
Exit For
Else
d(1) = 6
End If
d(2) = 4
ですから、
d(2) = d(2) - 1
Exit For
が実行され、d(2)=3となり、
For j = i + 1 To mx - 1
If d(j) > 0 Then
d(j) = d(j) - 1
Exit For
Else
d(j) = n - 1
End If
Next
が強制終了されます。
d(i) = d(i) + n
すなわち、
d(0) = d(0) + 7
によって、先に述べた
(※)
二桁目の1は一桁目から見ると10すなわち10進数の7です。
一桁目の財産は7を借りたことによって4 + 7 = 11
の 4 + 7 = 11の部分が実行されます。
最後に
c(i) = d(i) - e(i)
すなわち、
c(0) = d(0) - e(0)
から、
c(0) = 11 - 5 = 6
となります。
以上の計算から、
c(0) = 6 d(1) = 6 d(2) = 3
↓
が実現できています。
eclipse c++ 入門
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
vc++講義へ
excel 2013 2010 2007 vba入門へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
専門用語なしの C言語 C++ 入門(Visual C++ 2010で学ぶ C言語 C++ 入門)
専門用語なしの excel vba マクロ 入門 2013 2010 2007 対応講義 第1部
eclipse java 入門へ
excel 2016 vba 入門へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ