約 2,627,381 件
https://w.atwiki.jp/yaruo-schop/pages/575.html
◆WW.IweeeIE 氏 作品一覧 2011 やる夫で学ぶ「議論のしかた」 ▰▰▰▰▰▰▰▰▰▰▰▰ やる夫で学ぶ「議論のしかた」 最終更新:2023年10月03日 (火) 15時18分01秒 サムネイル画像 タイトル やる夫で学ぶ「議論のしかた」 作者名 ◆WW.IweeeIE 原作 オリジナル作品 ジャンル 学ぶ系 主人公 やる夫やらない夫 期間 2011/08/15~2011/08/23 掲示板 やる夫板II タグ 書き溜め、完結作品、短編作品 まとめサイト 様 泳ぐやる夫シアター 様 それにつけても金のほしさよ 様 ニートな2ちゃんねらー日記 様 論理的思考力と議論 様 スレッド一覧 スレッド名 タグ 備考 開始日時 最終レス やる夫で学ぶ「議論のしかた」 書き溜め 『やる夫で学ぶ「議論のしかた」』シリーズ:スタート『やる夫で学ぶ「議論のしかた」』シリーズ:完結 2011/08/15 2011/08/28 同作者の作品一覧 やる夫で学ぶ「議論のしかた」
https://w.atwiki.jp/tobebun/pages/7.html
動画(youtube) @wikiのwikiモードでは #video(動画のURL) と入力することで、動画を貼り付けることが出来ます。 詳しくはこちらをご覧ください。 =>http //atwiki.jp/guide/17_209_ja.html また動画のURLはYoutubeのURLをご利用ください。 =>http //www.youtube.com/ たとえば、#video(http //youtube.com/watch?v=kTV1CcS53JQ)と入力すると以下のように表示されます。
https://w.atwiki.jp/mopsprogramming/pages/168.html
再帰(Recursion)というのは、言ってみれば汎用アルゴリズムの一種で、ループとか条件構造と似たようなものです。何か特定の問題をうまく解くために開発された方法というわけじゃなくて、そういうやり方を使えばコードが明快になる場合がある、という感じですか。ただ、ループや条件構造よりも、少し論理的に込み入っているので、まあ、話としてはちょっと後にでてくるわけです。で、その実現(実装)の仕方についても、ちょっと入り組んだ話があるんで、その話もちょっと触れときます。これも少し長くなりそうな気配(^^;;)。 その理屈 本質的にはループと大して変わらなくって、定型的処理を必要な回数だけ繰り返して適用するのが、再帰です。再帰定理というのがあって、再帰とループは機能的に違いがないことが証明されているそうです。つまり、原理的には再帰で書けるコードはループで書けるんだそうで、じゃあ再帰なんてなくてもいいじゃんって話なわけですが、再帰の方がソースコードの意図が明瞭で簡単になる場合もあるってのが、その存在理由とされています。っていうか、Scheme(LISP系の関数型プログラミング言語)とかだと、繰り返し適用はループじゃなくて再帰を使うんだそうです。再帰をループよりも基本的としている言語から見れば、原理的にはループは再帰で書ける、と、同じ再帰定理でも逆に読むんですね。 話によると、再帰の理屈が理解できるかどうかが、最初の躓きの石なんだそうですね、プログラミング入門では。まあ、学校で習ったことのない私にはホントにところは解りませんが、なんで「躓く」のかというと、多分、まだ定義中のものを定義の中で呼び出すからじゃないでしょうかね。以前、タイプに関連してちょっと触れたラッセルのパラドクスの出発点の話みたいな感じがするんじゃないでしょうか。不確定なものを利用していいのか、と。ホントはループと同じようにちょっと前に戻るだけなんですが、ループには普通、はじめと終わりを標す括弧構造がありますからね。再帰には普通ないです。というか、再帰は、ひとつのワード(関数)という括弧構造を途中で分断してしまいます。初めは、順番に再帰より前の部分をぐるぐる回していって、抜けたところで、今度は再帰より後ろの部分を逆順にぐるぐる巻き戻す、というイメージです。 自分自身の中で自分自身を呼び出してたら、「合わせ鏡に映る私」みたいで際限がない感じがしますよね。でも、脱出口があるんですよ、再帰には、必ず。ループだって、それを抜けるポイントつくるのを忘れたり、脱出の条件が実は絶対に成就しない条件だったりすると、無限ループに入って大変な目にあったりしますよね。同じことです。ただ、ループの場合、処理が終わったよ、ってんで繰り返しを脱出しますが、再帰の場合、脱出条件が整ったところで初めて作業が開始される場合があるという違いがあります。投網かなんかを、ビヨーンと投げて、遠くに落ちたところで、ザザザざーっと引き寄せて魚を捕る、みたいな感じですかね。投網が一番遠くに達した点が、ここでいう「再帰の脱出口」に当たります。あるいは、昔よくあった、蛇腹みたいになってて、びょーんと伸びるマジックハンドで何か取る感じ、ですか。いやあれは縮むときにはモノを放しちゃうんでだめですね。最近は、何か特殊ゴムみたいのでできてて、びょんと伸びて、先にあったものをくっつけて取るという「カメレオンの舌」みたいなのがあるようですね。 いや、まあ、こんなイメージの話ばかりしててもしょうがないですね。「脱出口」というのは、ある条件下では自分自身をもう呼び出さない、というコードです。これはぜひとも必要になります。それと、繰り返し適用されるべき処理の本体、これを記述するコードもやはり必要になります。この本体部分は自分自身の呼び出しを含んでいていいことになります、というか、普通、含んでいます。一歩手前で自分自身を適用した結果を利用するのが、再帰の特徴ですから。この処理が、脱出口に達したところから、再帰呼出し自体のあとに書かれた処理が、だだだーっと、入れ子状に適用されていって、最終的に必要な結果を得ることになるのです。 Mops/Forthでの再帰 Mops/Forthでは、自分自身を呼び出すポイントに、"RECURSE"というワードを書くことになっています。他の言語では、SchemeでもCでもそのようですが、普通は、その関数の名前で呼び出すことになっているようです。Mops/Forthでは、既定義の同じ名前のワードを呼び出して少し変更したワードでオーバーライドできるようにするため、現在定義中のワードの名前は、意図的に隠しています。その代わり、コレは再帰ですよ、ということを明示するためにRECURSEというワードを準備したわけです。 階乗計算 簡単な例で説明しましょう。階乗計算をしてみましょう。5の階乗は1×2×3×4×5ということですよ、念のため。 Factorial ( u -- u! ) dup 0 = IF drop 1 EXIT THEN dup 1- RECURSE * ; かなり限定的なものですが、簡単なところで。階乗はすぐにでかくなるので、4バイト数だと、13くらいでもう溢れちゃうでしょう。上のコードの"EXIT"というのは、もうこのワードは抜けます、というワードです。これは使わないでも同じ働きをするコードは書けて、 Factorial ( u -- u! ) dup 0 = IF drop 1 ELSE dup 1- recurse * THEN ; となりますが、生成されるマシンコードは、多分、EXITを使った方が少し小さいと思います(あやふや)。後の方が、構造は分かりやすいかもしれませんね。つまり、このワード"Factorial"脱出口は、入力値が0以下となったところです。そのときには、入力値を捨てて、代わりに1を出力します。 もっと大きい入力のときはどうするかというと、入力値を複製し、一方を1減らします。そして、その減らした方の値を入力値としてRECURSEするわけです。つまり、その定義中のワードを呼び出します。そして、その出力をもとの入力とかけ算するのです。これが階乗計算の全貌です。 数学が得意な人なら、関数式で書くと一目瞭然でしょう。Factorialは、次のような漸化式で定義されているのです。 Factorial(0) = 1 Factorial(n) = n × Factorial(n-1) (nは自然数) Forthワードの定義との対応関係も分かりますよね。もうコレで、数列とかの漸化式が与えられたら、すぐにForthで書き下せますよね .... ってことはないかな、ヤッパリ(^^;;)。 基本は、本体関数を呼び出したいところにRECURSEと書く、ということになります。上のFactorialでは、 f(n) =n*f(n-1) なので、逆ポーランド式で書けば、 (n)f = n (n-1)f * なわけで、本体関数自体は、nをスタック入力として取ることを予定していて、定義内容も、スタック上にnが一つあることを想定して書きます。スタックの状態をコメントしていくと、 f \ -- n dup \ -- n n 1- \ -- n n-1 f \ -- n (n-1)f * \ n (n-1)f * ; となるわけです。定義内で呼び出されたfをRECURSEに置き換えて、 ; f dup 1- RECURSE * ; これは、脱出条件を省いた本体の定義になってますね。 フィボナッチ数列 じゃあ、簡単なのをもう一個。他のページでも扱いましたけれども、いわゆる、フィボナッチ(Fibonacci)数列です。これは、一個前の項との比が、黄金分割比に近づいていくってことでも有名ですね。漸化式からコードを書いてみましょう。"Fibonacci"って名前のワードにでもしましょうか。定義は、 Fibonacci(0) = 0 Fibonacci(1) = 1 Fibobacci(n) = Fibonaci(n-1) + Fibonacci(n-2) -- nは2以上の自然数 でいきましょう。型通り翻訳してみます。まず、脱出条件です。 Fibonacci ( u -- u ) dup 1 = IF 0 max EXIT THEN ... まあ、間違って負の数を入力する人のためちょっと誤摩化します。0と比べて大きい方の数値をとるというのが"0 max"です。0,1なら、それぞれ適当な出力がでることが分かりますよね。ここは脱出口なので、あとはEXITです。それから、本体ですね。ウンと改行して書きましょうかねえ。 ... \ -- n 1- \ -- n-1 dup 1- \ -- n-1, n-2 RECURSE \ -- n-1, (n-2)RECURSE=Fibonacci(n-2) swap \ -- Fibonacci(n-2), n-1 RECURSE \ -- Fibonacci(n-2), (n-1)RECURSE=Fibonacci(n-1) + \ -- Fibonacci(n-2)+Fibonacci(n-1) ; おしまいです。対応関係はわかりますね。合わせて普通に書くと、 Fibonacci ( u -- u ) dup 1 = IF 0 max EXIT THEN 1- dup 1- RECURSE swap RECURSE + ; コードは短い。観念的にも明快なので翻訳も簡単。ところが、このワードは絶望的に遅いのです。その理由は計算をいっぱい無駄に重複してするからなんです。概念的に簡潔で明快だが、そのままだと効率が悪い、というのが再帰の特徴ともいえます。再帰の効率の話は後で説明することにします。フィボナッチ数列なんかは、ループで書く方がずっと速くて、コードもそんなに難しくありません。というわけでループで書いてみると、 Fibonaci2 ( u -- u ) dup 1 = IF 0 max EXIT THEN 0 1 rot 1- FOR swap over + NEXT nip ; データスタックが少しごたごたしていて、コンパイルされるマシンコードも後者の方が長い程なんですけど、無駄に再計算したりしないので、圧倒的に速くなります。まあ、気が向いたら、RECURSE版とループ版とを、入力40くらいで比べてみてください。うちの機械ではRECURSE版は一瞬壊れたのかと不安になります(^^;;)。入力値があまり大きいと、これも1セルをはみ出しちゃいますので注意。 再帰は特に数理論理学では基本的な概念です。その意味では、アルゴリズムと相性がいいんでしょうね。これは基本的に帰納関数とか再帰関数(recursive function)という話に連なるものといえるでしょうね。Recursiveが「帰納」と訳されてるんですが、どうなんですかね。論理的な意味での帰納(個々のものについて成り立つことから普遍的に成り立つことを引き出す)とは意味合いは違います。帰納はinductionですが、いわゆる数学的帰納法ってのが、mathematical inductionというんですが、これもその実体はrecursiveな証明なんですね(^^;;)。まあ、数学ではrecursionのことをinducutionともいうのだと思えばいいでしょう。 帰納関数というのは、計算可能な、つまり有限の手順で結果が出せる処理、ということで、計算可能性の理論と密接な関連があるようです。でも、コンピュータプログラミングの仕組みとしてのRecursionと特別に結びつけるのはどうなんでしょうかね。というのは、帰納関数というのは、むしろ、特殊な関数というより、計算可能なアルゴリズム全般のことなんですよ。帰納関数なら計算できる、というのは分かっている。計算可能なら帰納関数か?そうだ、と主張するのがチャーチ(Church)のテーゼですね。でも証明できない。反例もないってことは、普通の計算はみな帰納関数なんですよ。足し算も。まあ、漸化式で書けるようなものは計算できるってわかってるんだから帰納関数であるということはそうなんでしょうけど、特に再帰のときだけ関連性を云々する意味はあまりないんじゃないですかね。 ちなみに、帰納関数とはどういう関数か、っていうことの定義も帰納的(recursive ^^;;)ですね。まあ、これは、計算可能性を重視する観点(Constructivism)からは全く自然なんですけどね。計算できる関数の有限個の合成として表現できるもの、ってかんじですか。五千八百兆回の計算で実現できる、ってのが本当に現実的に計算可能かってのは、この際、気にしないんですね(^^;;)。 多分、帰納関数のrecursiveは、ある有限アルゴリスムで得た結果に、また重ねてアルゴリズムを適用していくことを有限の範囲で認める、というところに注目しての命名と推測されます(多分、定義の仕方がrecursiveだからではないと思います)。コンピュータのRecurseも「重ねて適用する」というか「再施」という感じが共通ですけどね。要は一種の関数の合成なわけですが。気分は同じなんですかね。 再帰と効率 再帰はそのままやると、効率がよくありません。メモリー消費もバカにならない、といわれることもあります。どういうことなのでしょうか。 再帰は、ストレートに実装すると、現在定義中の関数(ワード)をそこで呼び出すという形式になります。問題は、その関数の呼び出しのときにどういうことが普通おこなわれているのかです。大抵の場合、入れ子になった呼び出しのときは、その呼び出しの都度、スタックに値を積んでいくようになっているのです。Forth系でいうと、いわゆるリターンスタックです。つまり、戻る地点のアドレスをメモリーに保存しておくんですね。それと、C言語系だと、帰るときにもとに戻しておかないといけないレジスタも保存します。さらに、局所変数もいっぱい使いますが、外に出て帰ってきたときに(呼び出しがリターンしてきたとき)局所変数の値が分からなくなっては困るので、呼び出しのときは、それらも保存します。関数への引数の現在値も呼出し前に保存しておかなければなりません。あれやこれや、C言語系では結構呼び出しには保存すべきものが多いんですね(値の状態をまとめて、"コンテクスト"とかいうようです。)。C言語系では各関数がスタックフレームと呼ばれるメモリー枠を確保して、そこに保存します。各関数は大抵自分専用のスタックフレームを確保します。そのフレームを関数呼出しの度毎に、まさにスタックのように積んでいくんですね。そのような各関数毎のスタックフレームはかなり大きくなる傾向にあります。それに入れ子の呼出しが嵩めば、スタックフレームはどんどん積もっていきます。例えば、ひとつの関数が20セル分(現実と比べるとかなり小さめではないかと思いますが)のスタックフレームを確保したとして、100回再帰すれば、総計2000セル分のスタックフレームが必要になるわけです。これに対して、ループは、ひとつの関数内で、実行箇所をちょっと前に戻すだけで済みます。いちいち、戻る毎にスタックを準備する必要がない。これが、「再帰はスタック(メモリ)を消費する」といわれていることの中身です。 まあ、メモリーが希少だった頃はメモリー効率の意味は大きかったんでしょうが、今では、アプリケーションレベルの話としてはそれほどともいえません(埋め込みとかだと、まだ問題になる)。ところが、再帰は、計算速度も遅くなるのです。というのは、再帰の度毎にメモリーに沢山の値を保存するわけです。以前の回で触れましたが、メモリーへのアクセスというのは、CPU内部での計算と比べて概して遅いわけです。呼び出しから戻るときには、レジスタを原状回復して戻すわけで、一旦保存された値は、この度はまた読み出されなければなりません。10アイテム分で10回の回帰だと、行きに100アイテム分の保存、帰りにまた100アイテム分の読み出し。たった10アイテムで10回の呼出しなのに、それだけのために200回という大量のメモリーアクセスをおこなうことになるわけです。 しかし、本当は、これは特に再帰だけの問題ではありません。関数(サブルーチン)の呼び出しそのものが、結構負担が大きいものなのです。再帰は、それをたくさんすることになる、というに過ぎません。この超過負担のため、C言語などでは、関数をできるだけ大きくして、他の関数の呼び出しを最小限に抑える方が、少なくとも実行速度の点では有利になっているのです。ただ、あまりにも長い関数を定義すると、何をやっているのか辿るのが大変になります。つまり、コードの保守性が落ちるというわけです。モジュラーなコードも書けなくなります。コンパイラがうまくやってくれることが多くなったそうですが、それでも、この実行速度と保守可能性のせめぎ合いは、速さが必要なコードでは、今でも大きな問題らしいです。 ここまで、C言語、C言語と言ってきたことにもお気づきでしょう。ここで言っている超過負担の問題は、よく考えてみると、関数、もっと広義の呼び名ではサブルーチンの呼び出しのときの仕組みがそうなっているからでてくるものだということに気付くでしょう。C言語では、標準的に、上のようなスタックフレームを作って、関数呼び出し時にたくさんのアイテムをそこに保存するという仕組みが採用されています。多くのコンピュータもそのような使い方をすることを前提につくられています。でも、そうしなきゃいけないってものではありません。別のやり方もありうるのです。ですが、そうはいっても、局所変数を使わない言語というのは、現在ではほとんどありません。呼び出しの前後で維持しておきたい局所変数は、その関数専用のスタックフレームを作ってどこかスレームに保存しておき、用がなくなったらフーレムメモリー領域ごと解放する、というのが一番効率がいいのです。そんなこんなで、スタックフレームを積む、というのが標準的なサブルーチンコールの方式なわけです(歴史的には逆かもしれませんが)。また、計算処理には遅いメモリーよりも、レジスタで計算したいため、レジスタの個数がいきおい増えてきています。いわゆるRISCと呼ばれるタイプのCPU(PowerPCもそれに含まれる)では、レジスタの個数はかなり多くなっています。値をメモリーにあるまま操作することはできず、必ずいったんレジスタに読み出すことになっているからです。サブルーチン呼び出しの前後で値を変えてはいけないレジスタというのも相当個数に上ります。かつてのMacで使われたPowerPCのCPUだと、大体、整数用と小数用、それぞれ20本ずつくらいが、値を変えてはいけないレジスタです。つまり、それらを使う場合には、いったんその値をメモリーに保存して、使った後は元に戻して返してやる必要があります。ちなみに、PPC Macintoshでは、これらのレジスタは局所変数のために使うとされています。レジスタでおさまりきれない局所変数は、メモリーを直接使います。結局、サブルーチン呼出しのときに必要になるメモリーアクセスの主要部分は、局所変数を使うために必要となる保存/回復操作であるということになります。 それなら、局所変数を使わないなら負担は軽くなるのか。実際その通りなのです。局所変数を使わない言語、といえば、もちろん、Forth系はまさにそうです。確かに、コードの行き先の方向転換をするだけでも、一本調子で実行が先に進むのと比べると平均的にはいくらかのロスはあります。それはループも同じことで、その点を更に最適化しようという話もあります。ですがその話は別とすると、Forth系は呼び出しの超過負担が非常に小さいことが特徴となっています。Mopsの場合も、局所変数を使えば使った分だけレジスタの保存/回復作業を必要としますが、それなしでやれば、呼び出されるワードへの入力のためのデータスタックと、戻るところを記録しておくリターンスタックアイテム一個分(ただし、2セル(64ビット)になっている)だけしか、メモリーとの遣り取りはありません。重複して保存されるアイテムというのもなく、必要最小限となっています。ですから、Mopsでは再帰の非効率がこの局面で問題になることはないと考えて良いと思います。ただ、このように、Mopsではもともと再帰があまり非効率的ではないせいか、あまり頑張って最適化しようとはしていません。後に述べるようなTail-Recurse最適化もないようです。いずれにせよ、その言語のサブルーチン呼び出しの仕組みが大きくかかわっているのです。Mopsは再帰それ自体は遅いわけではない言語ということになります。 再帰呼び出しの最適化 レジスターや、その他アイテムを保存-回復するための超過負担を軽減する簡単な最適化方法があります。LISPやSchemeなど、再帰を繰り返し適用の基本としている言語では、このような最適化は仕様として要請されてさえいるようです。いわゆる、末尾再帰最適化(tail-recursiton optimization)です。(訂正:LISPは末尾再帰最適化を仕様として要求するわけではないようです。言語仕様を見たわけではないので、あやふやですみません。Schemeでは仕様のようです。いずれにせよ、関数型言語は、再帰を繰り返し適用の基本形としているのは間違いないようです。ループの機構が無いわけではないらしいですが。) 実際には、これは再帰の最適化というより、サブルーチン呼び出し一般の最適化方法で、もっと広い意味では、tail-call optimizationと呼ばれています。末尾呼出し最適化、ですかね。 ただ、この最適化方法は、特定の局面でしか利用できません。その名が示す通り、[再帰]呼出しが、呼出しがわの末尾にある場合に限ってできるやり方なのです。末尾にある、とはつまり、呼出しがわの実体処理はもう終わっているので、呼び出した処理が終わって自分に処理が戻ってきた後は何もすることが残っていないという状態です。この状態で再帰呼出しをするように注意すれば、最適化が適用できて超過負担を軽減することができる、というわけです。 具体的には、まず、呼出し側には処理が残っていないのですから、そこで使われる局所変数は、もう呼出し前に保存しておく必要がありません。さらに、再帰で10段階呼び出しているとして、10番目が終わったら9番目に戻るわけですが、9番目に残っている処理は、8番目に戻る、ということだけです。なので、もう10番目から全部すっ飛ばして、一番最初に一気に戻ってしまえるわけです。で、一番最初(再帰を含んでいる関数)が呼び出されたときの状態を回復して振り出しに戻してやれば完璧です。で、再帰としてこの状況をもう一度考えると、保存するものもない、よって回復するものもない、自分自身の呼出しなんだから、出かけるのも自分自身の頭、戻ってくるところも自分自身のお尻と決まっているわけで、いちいち、お出かけの形を取る必要はないわけです。つまり、もともと、再帰するのにリターンアドレスの保存さえ不要なわけです。スタックフレームなどつくらず、普通に実行を頭に戻すだけのコードで書けるのです。再帰をこのような実行コードとしてコンパイル(ないし解釈)することを末尾再帰最適化というわけです。このようなことができるなら、再帰呼出しの特有の超過負担はほとんどなくなってしまうわけです。 用語法補遺:ちょっと、言葉の使い方について補足します。上で、末尾再帰最適化のことを大雑把に説明しました。再帰を用いているコードが末尾再帰になっているかどうかは型通りのチェックでわかりますし、型通りに単純な分岐ループ(頭に戻るGotoみたいなもの)に変形できるわけで、多くのコンパイラはこの最適化を自動的に行うようです。特に上にも書きましたがSchemeでは言語仕様として最適化が要求されていると聞いたことがあります。そのせいか、最適化されている末尾再帰という意味で、単に「末尾再帰」という言い方もときどき見かけます。なので、「末尾再帰」と聞いたら、言葉通り末尾で再帰をしているコードだという意味で言っているのか、最適化された再帰(つまり、効率が悪くない再帰)コードという意味で言っているのか、用心する必要があるようです。 Fibonacciはなぜ遅かったのか Mopsは再帰の超過負担が小さい、といいました。なのに、"Fibonacci"は、なぜ絶望的に遅かったのか。これは呼出し云々というより、再帰そのものの実装の問題なのです。前にもいいましたが、そのままでは無駄な計算が多すぎるのです。再帰の観念そのものには問題はないと私は思います。実現手順の問題です。いってみれば、その直前までに得た情報のほぼ半分を捨ててしまって、はじめから再計算しているのです。例えば、Fibonacci(5)を得るために、Fibonacci(4)とFibonacci(3)を得て、それを足し合わせたとします。じゃあ、次にFibonacci(6)に移ろうとしたときには、今得られたFibonacci(5)に、前にもう計算してあったFibonacci(4)を足せばいいわけじゃないですか。少なくとも、再帰関数の概念ではそういうものだと私は思います。ところが、上の二重のRECURSEを使ったコードでは、Fibonacci(5)は使いますが、Fibonacci(4)は0からまた再計算しているのです。七項目を得るときには、五項目は0から再計算、八項目を得るときには、六項目は再計算、、、という具合で、しかも各再計算の中身も、そこまで上がってくるまでに再計算のオンパレードです。それで、項目40ともなると、もうものすごい計算量なのです。ぼんやり考えると、計算の規模は2nよりちょっと小さいくらいですかね。計算自体がフィボナッチ数列みたいに増えていくんで、もしかして黄金分割比(1.6ちょっと)のn乗規模なんでしょうか --- 計算方法知らない(追加:おまけ付けました)。小さいnだと計算自体がフィボナッチ数列+1で増えていく感じなんで、40項目を計算するには初めの項のだいたい二億倍以上の時間がかかる感じです(^^;;)。 だいたいのイメージですが、関数"fibo(n)"と短くして-- そうしないと字がかぶっちゃう(^^;;) -- 、fibo(6)でどれくらい計算するかを図に書いてみました。二つの矢印が交わるところでひとつ足し算です。これを全部するんですよ。そいでもって、fibo(7)に上がるときは、左側のfibo(5)を頂点とした一房の部分を右側にもう一個くっつけて、それと、fibo(6)と足してfibo(7)です。かなり計算がダブってることが分かると思います。でかい絵ですみません(でも、結構、描くの大変だったんですよ、ええ。)。 比較のために、ループで計算するときの手順は次のような感じです。 上の足し算12個に対して、こっちは5個です。fibo(7)を計算するには、上ではあと8回足し算が増えますが、こっちはあと1個増えるだけです。 ここは、おまけ そんなわけで、再帰自体が悪いわけではない、ってことで再帰の再起を賭けて、再帰を使った速いフィボナッチを書いてみました。 Fib-Recurse ( u1 u2 #itm -- res ) dup R 0= IF nip R drop EXIT THEN swap over + R 1- RECURSE ; Fibonacci3 ( #itm -- res ) dup 0 = IF 0 max EXIT THEN 0 1 rot Fib-Recurse ; って、よーく見ると分かっちゃうんですが、実はこれは再帰のふりして実体はループなんですね。ループのコードのループ部分を再帰で書いただけなんですよ、実は。それでも、"Fib-Recurse"はまぎれもなく再帰を使ったコードですよねえ。こうするだけで速いんですよ。再帰は使い方を工夫しろ、ということでしょうね。 フィボナッチついでに、もっと大きい数も出せるやつを書いておきましょう。Mopsにはdoubleというライブラリファイルがついています。これは、小数の方じゃなくて、2セル整数を扱うためのライブラリです。これをつかって、64ビット数まで結果をだせるFibonacciを定義してみます。ループの方を使いますね。 まずPowerMops上で、 // double enter として、doubleファイルをロードしてください。それから、ワードを定義しますが、名前は、まあ、"Fibonaccid"とでもしときます。 Fibonaccid ( u -- ud ) dup 0 = IF 0 max s d EXIT THEN R 0 s d 1 s d R FOR 2swap 2over d+ NEXT 2swap 2drop ; これで、93項までは大丈夫です。計算は一瞬です。ただ、残される結果がダブル形式でよくわからないかもしれないので、終わった後に、 ud. enter としてみてください。負号なし64ビットだと完全に使い切れる桁は10進では19桁分だけですね。1.8446×1019程度を超えると溢れます。Schemeとかみたいに64ビット数を超える巨大数値計算のサポートは、いまのところないです(おそらく)。自分でライブラリを書く必要があります(多分)。 上で、再帰による遅くないFibonacci数列のコードを書きましたが、この中で再帰を含んでいるワード"Fib-Recurse"は奇しくも(?)末尾再帰になっています。PowerMopsでは別段これを分岐としてコンパイルするような最適化は働きませんが、それでも、十分速いものになっています。末尾再帰というのは要するに、再帰した結果に何らかの処理を加える必要がないような書き方をするということです。再帰を基本とするプログラミング言語では、できるだけ末尾再帰に持ち込めるように書け、といわれます。でも、それって、結局、ループで書くってことなんじゃないかという気がします。再帰のイメージとしては、まず初期条件が与えられていて、そこに至るまで準備していって、到達した地点からパタパタと計算して最終結果を得る、という感じだったんですが、末尾再帰というのは、抜けたときには全部終わってるんで、結局、初めから計算してるんですね。それは、ループのイメージに近い気がするわけです。ま、上のコードは、まさにループのコードを翻訳したんですけどね(^^;;)。 ストレートに再帰を適用した場合、具体的計算を留保しつつも第n項めから始めていって、端に至って最終的計算を開始する、という感じなんですが、上のようなコードの場合、実はいきなり初めの項から計算を始めてる。そして、再帰呼出しした自分自身にパラメターとして与えているのは、実は、残り項数なんですね。それ、まったくループのインデックスじゃないですか。ループのインデックスの値が破壊的に変更されるのがよくない、とか関数型言語ではいうわけで、それが再帰を好む一因となっているわけですが、う~んというかんじですねえ。関数への入力だから、その都度違っていいのか、そういうことか?ええっ?詭弁(イイノガレ)じゃねえのか?(^^;;)なら、MopsのFOR-NEXTループ版だって、ループのインデックスは使ってないぞ(使えるけど^^;;)。何か別のやり方もあるんでしょうかねえ。まあ、よくわかりません。 前へ 次へ 目次へ トップページへ
https://w.atwiki.jp/livly-wiki/pages/2.html
メニュー トップページ ページの編集について 自由に編集可能なページ のんびりダラーッとへ 情報提供フォーム リンクについて リンク集 初めての方へ リヴリーってなに? リヴリーの飼いかた リヴリーの世話のしかた doodoo(お金)の貯めかた 攻略メニュー リヴリー図鑑 モンスター図鑑 doodooリスト ワザリスト 餌リスト 島リスト アイテムリスト 公式パークリスト その他 リヴリー界用語 自殺リヴリーについて 荒らし行為について 各種の事件 ページ更新履歴 取得中です。 ここを編集
https://w.atwiki.jp/kt108stars/pages/6598.html
420 名前:NPCさん[sage] 投稿日:2011/12/08(木) 15 44 36.55 ID ??? まぁ、それでPLがGMをアテにしだしたりしなければいんじゃね。緊張感は保たれるし。 うちには「このキャラは○○だから」といって他のPLの支援を怠ったりする(リソースを消費しないものでも)事があるくせに、 おなじく「こういうキャラだから」でやらなくてもいい無茶やらかして「フォロー宜しく!」って他のPCのリソース切らせる奴居るわ。 421 名前:NPCさん[sage] 投稿日:2011/12/08(木) 15 47 14.64 ID ??? 設定のせいにして自己正当化する奴はその設定を作ったのは自分だということを綺麗に忘れてるよな 422 名前:NPCさん[sage] 投稿日:2011/12/08(木) 15 50 46.34 ID ??? PCの行動を決定するのはPLなんだから融通してくれ 理由付けなんてどうにかなるだろと思う時は多々ある 423 名前:NPCさん[sage] 投稿日:2011/12/08(木) 16 25 15.20 ID ??? 420 「こういうキャラだから」で放置してやれ それでギャーギャー言うなら鳥取の存続を掛けて話し合いだ スレ298
https://w.atwiki.jp/tops/pages/4.html
ニュース @wikiのwikiモードでは #news(興味のある単語) と入力することで、あるキーワードに関連するニュース一覧を表示することができます 詳しくはこちらをご覧ください。 =>http //atwiki.jp/guide/17_174_ja.html たとえば、#news(wiki)と入力すると以下のように表示されます。 マニュアル作成に便利な「画像編集」機能を提供開始! - ナレッジ共有・社内wikiツール「NotePM」:時事ドットコム - 時事通信 マニュアル作成に便利な「画像編集」機能を提供開始! - ナレッジ共有・社内wikiツール「NotePM」 - PR TIMES 【アイプラ】リセマラは必要?当たりキャラランキング【IDOLY PRIDE】 - Gamerch(ゲーマチ) 篠原悠希×田中芳樹が明かす「歴史ファンタジー小説ならではの悩み」(現代ビジネス) - Yahoo!ニュース - Yahoo!ニュース 【Apex Legends】ヴァルキリーの能力と評価【エーペックス】 - Gamerch(ゲーマチ) モンハンライズ攻略Wiki|MHRise - AppMedia(アップメディア) 【ウインドボーイズ】リセマラ当たりランキング(最新版) - ウインドボーイズ攻略Wiki - Gamerch(ゲーマチ) ポケモンBDSP(ダイパリメイク)攻略wiki - AppMedia(アップメディア) 【テイルズオブルミナリア】リセマラ当たりランキング - TOルミナリア攻略Wiki - Gamerch(ゲーマチ) SlackからWikiへ!シームレスな文章作成・共有が可能な「GROWIBot」リリース - アットプレス(プレスリリース) 【ダンカグ】登場キャラクターと担当声優一覧【東方ダンマクカグラ】 - AppMedia(アップメディア) 【ウマ娘】チャンピオンズミーティングの攻略まとめ - Gamerch(ゲーマチ) 【ウマ娘】ナリタブライアンの育成論|URAシナリオ - Gamerch(ゲーマチ) ドラゴンクエストけしケシ攻略Wiki - Gamerch(ゲーマチ) サモンズボード攻略wiki - GameWith 【スタオケ】カード一覧【金色のコルダスターライトオーケストラ】 - Gamerch(ゲーマチ) 【スマブラSP】ソラのコンボと評価【スマブラスペシャル】 - Gamerch(ゲーマチ) 【ブレフロレゾナ】リセマラ当たりランキング【ブレイブフロンティアレゾナ】 - ブレフロR攻略Wiki - Gamerch(ゲーマチ) 【ポケモンユナイト】サーナイトの評価と性能詳細【UNITE】 - Gamerch(ゲーマチ) 仲村トオル、共演者は事前に“Wiki調べ” - 沖縄タイムス 【ENDER LILIES】攻略チャートと全体マップ【エンダーリリィズ】 - Gamerch(ゲーマチ) 【ウマ娘】あんしん笹針師の選択肢はどれを選ぶべき? - Gamerch(ゲーマチ) 【ポケモンユナイト】アップデート情報・キャラ調整まとめ - ポケモンユナイト攻略Wiki - Gamerch(ゲーマチ) 【Apex】シーズン11の新要素と最新情報まとめ【エーペックス】 - Gamerch(ゲーマチ) ロストジャッジメント攻略Wiki - Gamerch(ゲーマチ) 【Among us】新マップThe Airship(エアシップ)の解説【アモングアス】 - Gamerch(ゲーマチ) ハーネスについて小児科医の立場から考える(坂本昌彦) - 個人 - Yahoo!ニュース - Yahoo!ニュース ゼルダ無双攻略Wiki|厄災の黙示録 - AppMedia(アップメディア) ウマ娘攻略Wiki - AppMedia(アップメディア) 【まおりゅう】最強パーティー編成とおすすめキャラ【転スラアプリ】 - Gamerch(ゲーマチ) ゲトメア(ゲートオブナイトメア)攻略Wiki - Gamerch(ゲーマチ) 【白夜極光】リセマラ当たりランキング - 白夜 極光 wiki - Gamerch(ゲーマチ) お蔵入りとなった幻の『スーパーマリオ』 オランダの博物館でプレイ可能?(リアルサウンド) - Yahoo!ニュース - Yahoo!ニュース ナレッジ共有・社内wikiツール「NotePM」が「ITreview Best Software in Japan 2021」のTOP50に選出 - PR TIMES 真女神転生5攻略Wiki|メガテン5 - AppMedia(アップメディア) 【B4B】近接ビルドデッキにおすすめのカード【back4blood】 - Gamerch(ゲーマチ) 【ウマ娘】サイレンススズカ[サポート・配布SSR]のイベントと評価 - Gamerch(ゲーマチ) ポケモンスナップ攻略wiki - AppMedia(アップメディア) 富野由悠季「ブレンパワード」作り直したい!ファンを前に意欲(シネマトゥデイ) - Yahoo!ニュース - Yahoo!ニュース 【スマブラSP】カズヤの評価とコンボ【スマブラスペシャル】 - Gamerch(ゲーマチ) ナレッジ共有・社内wiki「NotePM」が「ITreview Grid Award 2021 Fall」で、チームコラボレーションとマニュアル作成部門において「Leader」を5期連続でW受賞! - PR TIMES メモ・ドキュメント・wiki・プロジェクト管理などオールインワンのワークスペース「Notion」が日本語ベータ版提供開始 - TechCrunch Japan 【ギアジェネ】リセマラ当たりランキング【コードギアス】 - ギアジェネ攻略Wiki - Gamerch(ゲーマチ) モンスターファーム2(MF2)攻略wiki|アプリ・Switch移植版 - AppMedia(アップメディア) 【ブラサジ】最強キャラTierランキング【ブラックサージナイト】 - Gamerch(ゲーマチ) 【パワプロ】鬼滅の刃コラボ情報まとめ - Gamerch(ゲーマチ) 【SPAJAM2021】第3回予選大会は「クイズ!WIKIにゃんず!」を開発したチーム「かよちゃんず」が最優秀賞! | gamebiz - SocialGameInfo 検索結果における「ナレッジパネル」の役割とは・・・ウィキメディア財団とDuckDuckGoの共同調査 - Media Innovation 【FGO】サーヴァントコインの入手方法・使い道 - AppMedia(アップメディア) ナレッジ共有・社内wikiツール「NotePM」が「BOXIL SaaS AWARD 2021 Autumn」にて「コラボレーション部門」を受賞! - PR TIMES 【ロストジャッジメント】「タイムカプセルのゆくえ」の攻略チャート【ジャッジアイズ2】 - AppMedia(アップメディア) 「ゼルダの伝説 BotW」のマラソンで23秒? 驚きの速さで完走した方法が話題(リアルサウンド) - Yahoo!ニュース - Yahoo!ニュース Wikipediaが「中国人編集者の身の安全を守るため」に一部の編集者アカウントをBANに - GIGAZINE 【ドッカンバトル】3.5億ダウンロードキャンペーン最新情報 - ドッカンバトル攻略Wiki - Gamerch(ゲーマチ) BTS(防弾少年団)のV、8月のWikipedia閲覧数が韓国アーティストで1位!グループでは4ヶ月連続トップ - Kstyle 【イース6オンライン】リセマラ当たりランキング|召喚ガチャの開放条件は? - Gamerch(ゲーマチ) BacklogからNotePMへwiki情報を自動API連携する「Backlog to NotePM」をSaaStainerに掲載開始 - PR TIMES ライザのアトリエ2攻略Wiki - AppMedia(アップメディア) 真女神転生3リマスター攻略Wiki|メガテン3 - AppMedia(アップメディア) ガーディアンテイルズ(ガデテル)攻略Wiki - Gamerch(ゲーマチ) タスクも文書もWikiもデータベースもまとめて管理できる「Notion」とは? - ASCII.jp ナレッジ共有・社内wikiツール「NotePM」が、見るだけ専用ユーザー『無料』の新プランを発表! - PR TIMES 【かのぱず】リセマラ当たりランキング【彼女お借りします】 - Gamerch(ゲーマチ) 【乃木フラ】リセマラの必要はある?【乃木坂的フラクタル】 - Gamerch(ゲーマチ) メトロイド ドレッド攻略Wiki - Gamerch(ゲーマチ) 【グランサガ】リセマラ当たりランキング - グランサガ攻略wiki - Gamerch(ゲーマチ) 【パワプロ】生放送まとめ|パワフェス2021 - パワプロ攻略Wiki - Gamerch(ゲーマチ) 【ポケモンユナイト】サーナイトのおすすめビルド(わざ・持ち物) - Gamerch(ゲーマチ) ルーンファクトリー5攻略wiki|ルンファク5 - AppMedia(アップメディア) 【ふんクロ】リセマラ当たりランキング【シャーマンキング】 - ふんクロ攻略Wiki - Gamerch(ゲーマチ) 簡単操作で自分専用Wikiを構築できるMarkdownエディタ「Obsidian」のモバイル版を使ってみた - GIGAZINE ディーサイドトロイメライ攻略Wiki - Gamerch(ゲーマチ) 情報マネジメントツール「Huddler」がwiki機能を刷新 - PR TIMES シェアエコ配送アプリ「DIAq(ダイヤク)」のアンカーアプリで、高層ビル・商業施設の入館方法などお役立ち情報をまとめた「DIAqwiki」を公開 - アットプレス(プレスリリース) 異常熱波のカナダで49.6度、いま北米で起きていること(森さやか) - 個人 - Yahoo!ニュース - Yahoo!ニュース 【ツイステ】マスターシェフの攻略~辛味のふるさと~【料理イベント】 - Gamerch(ゲーマチ) 【ラグナロクオリジン】リセマラは不要?おすすめ職業は?【ラグオリ】 - Gamerch(ゲーマチ) 白夜極光攻略wiki - AppMedia(アップメディア) 【バイオミュータント】2.02アプデ|アップデート1.4情報 - バイオミュータント攻略Wiki - Gamerch(ゲーマチ) エッチな犯罪許しません! 『電脳天使ジブリール』サービス終了に落涙 - 電撃オンライン ニーアレプリカントリメイク攻略wiki|ver.1.22 - AppMedia(アップメディア) アイプラ攻略Wiki|アイドリープライド - AppMedia(アップメディア) 【ウマ娘】ゴルシウィークはいつから?キャンペーン情報まとめ - Gamerch(ゲーマチ) シーズン66 - 【超速GP】ミニ四駆 超速グランプリ攻略まとめwiki - 電撃オンライン 乃木坂的フラクタル攻略Wiki - Gamerch(ゲーマチ) 「こんなことになるとは…」13年前のエイプリルフールについた“嘘”がネットで… ある男の告白(BuzzFeed Japan) - Yahoo!ニュース - Yahoo!ニュース 整理不要の情報共有ツール(社内Wiki)「Nerve」シードラウンドで総額約3500万円の資金調達を実施 - PR TIMES 【ウマ娘】隠しイベントの発生条件と効果まとめ - Gamerch(ゲーマチ) Nerve - 整理不要の情報共有ツール(社内Wiki) ローンチカスタマー募集開始のお知らせ - PR TIMES Among Us攻略Wiki【アマングアス・アモングアス】 - Gamerch(ゲーマチ) 【ひなこい】最強ひな写ランキング - ひなこい攻略Wiki - Gamerch(ゲーマチ) 稲作アクションRPG『天穂のサクナヒメ』における「農林水産省攻略wiki説」は本当なのか? - AUTOMATON 無料とは思えない多機能っぷりなWikiインフラ「Wiki.js」レビュー、自前でホスト&外部サービスと連携可能 - GIGAZINE Microsoft Teamsの基本と活用(24) TeamsのWikiを使う - マイナビニュース 『ゲーミングお嬢様』での提起が話題に “企業系wiki”に横たわる問題点とは - リアルサウンド 「エイリアンのたまご」,自動周回機能と公式wikiが登場 - 4Gamer.net 【リゼロス】Re ゼロから始める異世界生活 Lost in Memories攻略まとめwiki - 電撃オンライン ヌーラボ、「Backlog」の絵文字入力の補完機能やWiki編集の自動マージ機能を改善 - CodeZine(コードジン) ヌーラボ、プロジェクト管理ツール「Backlog」の絵文字入力の補完機能・Wiki編集の自動マージ機能を修正改善 - PR TIMES Backlog、Wikiにファイル添付が容易にできる機能をリリース -- グローバルバーの視認性改善なども実施 - PR TIMES
https://w.atwiki.jp/cod_bo3/pages/23.html
クラン一覧 PS4 ページ1 順番に登録して下さい 全ページ中1クラン1登録のみ重複登録禁止 バナーのサイズは300px×80px以内にして下さい性的・暴力・中傷を含む画像禁止 登録クランにつながるリンクやURLまたは連絡用アカウントを必ず記入して下さい レイアウトが崩れないようプレビュー確認してページ保存して下さい。 紹介文は色変更、顔文字、記号、段落等で装飾せず概要と目的を簡潔な文で4行以内に収めて下さい。誹謗・中傷・煽り含む文字禁止 登録No.20以上は新たなページに登録して下さい。 悪質な行為(談合/グリッチ勧誘及び誘致・中傷等での晒し等)が確認出来るクランの登録は削除対象となります 登録No. クラン名[タグ] 在籍人数 バナー・ホームページ・連絡用アカウント等々(300px×80px以内) 紹介文・募集内容※必須(4行以内) 更新日 01 NoLaN[NLN] 25名 メンバーは18~32歳で9割が社会人です。主にはランクマTDMですがDOM,S Dもやります。募集要項はhpご覧下さい 2016/05/28 02 Collection of Always[COA] 17名 images.php?file=8126825728.jpg 主にTDMしてます。VCでコミュニケーションの取れる向上心のあるin率高い方募集。興味ある方は連絡下さい 2015/10/14 03 Soul face[SOUL] 8名 images.php?file=4305889601.jpg 学生~社会人まで仲良く活動してます。初心者でも大歓迎。連絡待ってます 2015/10/28 04 O.R.C.A.[ORCA] 38名 エンジョイクランですが勝利にも拘ります。詳しくはhpご覧下さい 2015/10/28 05 Clan Rin[RIN] 3名 images.php?file=9714853804.jpg エンジョイしつつも"勝つ"をモットーに活動してます。老若男女問わず募集中。興味ある方はhpご覧下さい 2015/11/01 06 Dudleyz Japan[DZJP] 3名 上手い方から初心者まで大歓迎!交流戦も募集中。詳しくはhpご覧下さい 2015/11/20 07 GLFD FPS clan[GLFD] 14名 index.php?module=preview file=0757597712.jpg エンジョイクランです。初心者から、お子さんがいる方でも大歓迎。詳しくはhpご覧下さい 2015/11/03 08 WizU DualPistols[WIZU] 5名 images.php?file=4498870661.gif 「皆で頑張り助け合おう!」がモットーです。k/d・IN率・VC不問。聞き専OK!気軽にどうぞ 2015/11/06 09 TRUST[TRST] 9名 images.php?file=0831841037.png 主にDOM,TDMしてます。CyAC S Dも行います。詳しくはhpご覧下さい 2015/11/06 10 Clan-OZ[OZ] 40名 主にDOM,TDMしてます。やる気溢れるメンバー募集中(VC必須)詳しくはhpご覧下さい 2015/12/20 11 [] ref 12 CopOfJoe[COJ] 10名 images.php?file=1799863763.jpg 一杯のコーヒーで一息つくような雰囲気で仲間と楽しみませんか?メンバーは20代で個性豊かです。交流戦募集中 2016/01/13 13 Brassiere Hock[BH] 11名 メンバー募集中。詳しくはhpご覧下さい 2016/01/16 14 Dull Unit[DU] 5名 CLAN-Banner.jpg 40代の社会人クランです。メンバー募集中。詳しくはhpへ 2015/11/26 15 DOLL[DOLL] 12名 S DクランですがDOMもやります。メンバー・交流戦募集中。詳しくはhp迄 2015/11/28 16 MOHK[MOHK] 10名 images.php?file=7442923372.jpg 「楽しくわいわい」「勝利」がモットーのエンジョイクランです。募集停止中。詳しくはhpご覧下さい 2015/11/29 17 TNPN[TNPN] 100名 クランというよりただ集まってゲームをする集団、気軽にどうぞ。skypeの使用ができる18歳以上(高校生不可)条件を満たしている方なら誰でも大歓迎詳しくはHPを参照に。 2016/07/10 19 花子、空に唄えば[HNKS] 20名 images.php?file=5724443274.jpg メンバー募集中(VC・twitter必須)twitterからの連絡お待ちしてます。宜しくお願いします 2015/12/09 20 RE!S[REIS] 15名 20~30代が所属してます。メンバー募集中。21~25時まで主にTDM,S Dしてます 2016/01/11 ※登録No.20以上は新たなページに登録して下さい
https://w.atwiki.jp/mopsprogramming/pages/128.html
ワードをコンパイルすれば、対応するマシン語がMops辞書のコード領域に書き込まれます。ここでの話は、このような間接的効果としてではなくて、直接にコード領域に書き込む方法です。 CODE, ( n -- ) PPCのマシン語は32ビット(4バイト)です。ですから、マシン語がわかれば、それを直接辞書に書き込むということもできます。この場合、当然、4バイト幅の数値として書き込みます。このためのワードは、CODE, ( n -- )です。このワードはトップスタックの値を、辞書のコード領域の空き部分の頭(CDP)からの4バイト幅に、4バイト数としてコンパイルし、CDPを4バイト先に進めます。これを使って、例えば、 $ 7C641B78 CODE, \ or r4,r3,r3 // "レジスタ3の値をレジスタ4にコピー"をコンパイル(PPCマシンインストラクション) などとやることもできますが、よほどのことがない限りこんなことはやりませんし、普通、やりたくもありません。 実際には、辞書のコード領域は、実行可能なコードを書き込まなければならない場所という意味ではなく、読み出しのみ(Read-Only)のデータを書き込む場所、と考えるのが適切です。Read-Onlyということは、いったん書き込んだなら、変更できないということを意味します。この性質をつかって、OSは検索の効率化を図っているのです。ですから、後で変更の必要がないことがわかっているデータなら、コード領域に書き込んでおいて検索効率を上げる(最適化する)という使い方もあり得るわけです。 そのため、マシンインストラクションに対応する32ビット数値だけではなくて、データ領域へのコンパイルとちょうど対応する、いくつかのコードコンパイル用ワードが準備されています。 CODEC, ( c -- ) CDPから1バイトに、1バイト数としてトップスタック値をコンパイルし、CDPを1バイト進めます。 CODEW, ( n -- ) 上の"1バイト"を"2バイト"に読み替えれば、全く同じです。 CODEN, ( addr len -- ) メモリーアドレス"addr"から始まる"len"バイトのデータを、CDP以降にコピーした上で、CDPを"len"バイトだけ進めます。 メモリーは4バイトセルを一つの単位にしており、セルによってきちんと区切られていないと、コードを識別できません。ですから、"CODE,"以外のワードでコード領域にコンパイルした結果、境界線が半端になりそうなときには、実行コードのコンパイル前に"Code_Align"を実行しましょう。適当な分量の詰め物(0)によってCDPが4の倍数に揃います。 関連項目: データをコンパイルする Mops辞書 トップページへ 目次へ
https://w.atwiki.jp/stellaris/pages/21.html
Setiechinopsis mirabilis [奇想丸] 刺 実
https://w.atwiki.jp/mopsprogramming/pages/58.html
局所変数とは、一つのワードの実行中のみ有効で、一度そのワードを抜けるとその時点で廃棄されてしまう変数のことです。Mopsには二種類の局所変数が実装されていますが、ここでは、明示的に値を割り当ててから使う局所変数について述べます。 データスタックを擁するForth系開発環境では、一般には、局所変数に対する態度は冷淡です。本来、スタックを使うべきだからです。これに対して、Mopsでは局所変数に対しても十分な最適化が施され、場合によってはスタックのみに頼るよりも、局所変数も組み合わせて使う方が、実行速度が上がる場合があります。 局所変数は、次のような構文で宣言します。: MyWord { \ local1 local2 -- } ..... つまり、その局所変数の有効範囲となるワードの定義の中、ワード名の後、実際のコードが始まる前に、中括弧(curly bracket)を用いてスタック効果コメント類似の宣言を書きます。その中の、破線(二つの連続したマイナス記号)の左側にバックスラッシュ(ブラウザによってはyenマークで表示されているかもしれません)を置き、これらの間に局所変数を宣言するのです。 これらの局所変数local1およびlocal2は通常0で初期化されています。値の操作の構文は、増減も含めてValue変数と同様です。: 63 - local1 \ 値63(=その時点でのトップスタック値)を格納 local1 \ 格納された値をトップスタックに返す 1 ++ param2 \ param2の格納値を1(=その時点でのトップスタック値)増やす(足し算する) 2 -- param2 \ param2の格納値を2(=その時点でのトップスタック値)減らす(引き算する) 局所変数は原則としてレジスタ変数として実装されているため、格納場所のメモリアドレスは存在しません。 局所変数は、それが宣言されているワードの一回の実行中は有効で、値も維持されます。いったんそのワードの実行を抜けてしまった後は、再び呼びされても、以前呼び出し時の値は保持されていません。 浮動小数点数のlocal (flocalsなどともいう)が必要な場合には、名前を%で始めます。 MyWord2 { \ loc1 loc2 %floc1 %floc2 -- } ..... - %floc1 .... 1.0 ++ %floc2 ... 使い方は整数の場合と同じですが、値は小数スタックを経由して処理されます。 効率性への配慮については、名前付き引数のページを参照してください。 関連項目: 名前付き引数 変数格納値の増減 データスタック テンポラリオブジェクト 自動Late Bind ローカルセクション メソッドのローカルセクション トップページへ 目次へ