第20講 n進数演算−−−引き算
第7話 引き算プログラム解説その2
wgiuqh
を実現するプログラム主要部分再掲
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
前話では、
0321
赤い囲いの表示まで解説しました。
今話はその下の引き算がいかに行われているかを解説します。
  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)を挿入しています。
0321
シートの-の表示のために必要な処置です。
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
を解説しましょう。
cda
zdg
を例にして説明しましょう。
すなわち、
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個ですから、
zdg
を範囲にしています。
実際の個数を数えて下さい。
上は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
 ですが、
 ww
 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
 ww
  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
 ww
             ↓
 qnkqwiu
 が実現できています。



第6話へ 第8話へ
004

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入門へ
本サイトトップへ