abacus.jpg


そろばん

 そろばんをモデリングして、計算させてみようと思います。
 昔、小学生の頃だったか、「そろばん塾」に通ったことがあります。その後も、あんまり暗算とかは得意ではないし、何より、そろばんを使った計算の方法は、もう欠片すら頭に残ってはおりませぬが……。単なる加算くらいなら、今から調べ直しても、何とかなるかな?、くらいな者です。

そろばんのモデリング

 日本のそろばんは、1桁に5つの玉が連なっています。5つの玉は、「梁」と呼ばれる横棒で、上の1つと下の4つに分離されており、上の1つを「五玉」、下の4つを「一玉」と呼ぶそうです。桁と玉がバラバラにならないように、外側を枠で固定すると、「そろばん」になります。
 この形って、日本で昔から使われていた物、何ですよね?って、紹介している作者が聞くのも何ですが……。と、言うのは、梁の部分に何桁毎かに印(「定点」と呼ぶようです)がついているのですが、どうやら、今のそろばんは、千進法(3桁毎)で印がついているみたいです。
 ずっと昔の人たちは千進法で数を数えていたのでしょうか?日本の文化は、中国から伝わった文化が色濃く反映されているので、万進法(4桁毎)かと思っていました。

  132,415,687円

 もう慣れてしまいましたが、この数字を見て、パッと「1億3千2百万…円」と浮かぶまでには、結構慣れが必要でした。

  1億3241万5687円 または、1,3241,5687円

 上の様に、4桁区切りにした方が、日本の文化的には読み易いのに……。


 塾に通っていた時に使っていたそろばんは、手元には残っていませんが、さすがに「木製」だった気がします。よって、前回(「つげ櫛」で)作った「つげ」のマッピングデータを使いまわすことにします。

※ちょっとお高そうな、「つげのそろばん(別ウインドウが開きます)」なんてあるの?と思って検索したところ、あるみたいですね。

素数を求める

 今回のメインテーマは、「そろばんを使って計算している様子」を動画にすることです。
 そろばんを使った計算は、「加算」くらいしか対応できそうにないので(他は忘却の彼方)、ただ単に、数列を加算して行こうと思います。1から順に足してもあまり面白くないので、最初に素数を求めておいて、素数を順に足していく動画にしようと思いました。

 と、言うことで、まずは素数を求めるところから始めます。素数とは、「1と自分自身以外に割り切れない数」ですから、X=2から始めて、「自分自身−1」までの間に、余りが0になる数値Xが見つかったら非素数、見つからなければ素数と、判定します。

※もし、割り切れるとすると、最小の商は2のはずなので、「自分自身÷2」で判定を打ち切ると、ちょっと高速化できますね。

 Xi-TRACEのデータでは、以下の様になります。

  // 素数を求める
  var idx;
  var idx2;
  var pnum0;
  idx=2;
  while (idx<NP)
  {
    idx2=2;
    while (idx2≦idx/2)
    {
      if (idx%idx2=0)
      {
        break;
      }
      // 継続
      idx2=idx2 + 1;
    }
    if (idx2>idx/2)
    {
      // 素数
      static : var prim#(pnum0)=idx;
      pnum0=pnum0 + 1;
    }
    // 継続
    idx=idx + 1;
  }


 こんな感じなので、判定する数値が大きくなればなるほど、判定に時間がかかります。上のコードでは、変数NP未満の素数をリストアップして、配列prim#(idx)に蓄積します。
 後ほどリンクする完成版のデータでは、加算と加算の間に一呼吸開けるため、配列prim#(idx)に素数以外の"0"をいくつか挿入しています。

そろばんで加算する

 次は、そろばんで加算する様子をシミュレートします。
 「1,968+235」を計算してみましょう。そろばんでは、まず、定点に合わせて、「1,968」を打ち込みます。そこに「235」を加えるのですが、最初に「200」、次に「30」、最後に「5」を足し込んでいって、目的を果たします。

 上のような手順を、1ステップづつCGに起こしていくと、そろばんで計算しているような動画が完成します。

※ああ、でも、やっぱり覚えていないな……。桁上げって、上の手順みたいに、後からやるんでしたっけ?指2本使って、同時にやっていたような記憶もアリ……。「4 → 5」にする時も、指1本で「五玉を下げる → 一玉4つを下げる」と、言う手順じゃなかったっけ?忘れちゃったな〜。

 被加算数abac(=1,968)、加算数addc(=235)を、各桁毎に配列変数に分割するのは以下の様になります。

  // 各桁に分離
  idx=0;
  while (idx<NC)
  {
    abac#(idx)=round (abac)%10;
    addc#(idx)=round (addc)%10;
    abac=floor (abac/10);
    addc=floor (addc/10);
    // 継続
    idx=idx + 1;
  }


 この場合、配列の添え字0がLSB側で、添え字が大きくなるとMSB側となっています。

 すると、1ステップ分の演算は、以下の通り。

  // 1ステップ演算
  idx=NC - 1;
  while (idx>=0)
  {
    if (addc#(idx)!=0)
    {
      abac#(idx)=abac#(idx) + addc#(idx);
      addc#(idx)=0;
      if (abac#(idx)>9)
      {
        // 桁上がり
        abac#(idx)=abac#(idx)%10;
        addc#(idx + 1)=1;
      }
      lstx=NC/2 - idx - 2;
      break;
    }
    // 継続
    idx=idx - 1;
  }


 加算数addcの上位桁から、0ではない桁を探す → その桁を加算する → 桁上がりを判定して、addcの上位桁にセットする、こんな手順です。これを、addc=0になるまで繰り返すと、ようやく1回分の加算(abac=abac+addc)が終了します。

 レイトレーシングしながら、このステップを計算していくのは、ちょっと難しいので、レイトレーシングデータとは別に、そろばんによる演算ステップをテーブルに出力するスクリプトを作っておきました(abacus_table.xitr)。レイトレーシングに先立って、1回実行してください。


完成データ

 完成したデータをリンクしておきます。

1) Xi-TRACEデータ abacus.xitr
2) マッピングデータ comb_tuge.jpg
3) 演算ステップ計算 abacus_table.xitr

 1)と2)でレイトレーシングを実行します。レイトレーシングの際に、3)で作成したテーブルファイルが必要となりますので、レイトレーシングを実行する前に、一度、3)を実行してください。



 800未満の素数をすべて、そろばんで加算しています。最後の素数は797で、2から数えて139個、合計は50,078でした。「ごめいさん」……たぶん。


home

download

gallery