生きてりゃいい、生きてりゃ勝利なんていうのは動物の話だ・・・オレは人間だ!

最強伝説黒沢 5 (5) 最強伝説黒沢 5 (5)
コンビニにいったら陳列されてたので買ってしまった。
4巻が発売されたのってつい最近だった気がするんだけど。

なんつーか、最近福本さんの漫画、話の密度が薄くなってる気がする。 カイジもアカギも黒沢も。
この黒沢5巻も心にしみいる福本節がなかった。
ちょっと大量生産しすぎなんじゃないかな。

Game Programming Gems 3

Game Programming Gems 3 (Game Programming Gems Series 3) Game Programming Gems 3 (Game Programming Gems Series 3) の日本語版が今日発売のはずだが、いまだに amazonの商品リストには 入ってないなあ。なんだだろ。
楽チンだから amazonで買おうと思ってたのに。しょうがない、本屋巡りの旅に出かけるか。浜松だと中途半端な大きさの本屋ばっかりで、「 ここ行けば必ず買える!」って本屋がないから大変なんだよなあ。

それにしても楽しみだ。このシリーズの日本語版は 1冊12,800円とかなり高いが、十分にその価値はある。
というか、ゲームのプログラム書いたことないので、ゲーム屋さんにとってどのくらい価値があるものなのかはよくわからない。
むしろゲーム以外の分野において、ゲーム屋さんで培われたさまざまなテクニックをつまみ食いできるところがいいんではないかと思う。

C++の設計と進化

C++の設計と進化 C++の設計と進化
ストラウストラップが C++の進化の歴史についてまとめた本。発売はまだ先かと思っていたらLAOXで平積みされてた。
まだ途中までしか読んでないけど、「C++のこの部分の仕様はこの言語を参考にしていて、こうしなかった理由はこういう問題があったから」といったのが細かく書かれていてかなり面白い。

ちなみに C++ という名前を決めるにあたって、その名前を多数の応募の中から選んだらしく、1位が C++ で 2位が ++C だったとのことだ。
教育的な側面からも ++C にして欲しかった。
というのもその効率の悪さにもかかわらず、++演算子を後置で使うコードがあまりに多いからだ。
僕も 68000のアセンブラからプログラミングの世界に入ったので、++は後置で使う癖が最初はついていた。68000のアドレッシングモードにポストインクリメントはあるがプリインクリメントはなかったからだ。
その上、C++ が言語名だったので ++ は前置よりも、後置の方がどちらかといえば主役と思ってしまったのだと思う。
ということで、もし ++C という名前だったら 「++の後置版は遅い」というTIPSを知らなくても、みんな前置で書いたのにと思う次第なのである。

HACKING

Hacking:美しき策謀―脆弱性攻撃の理論と実際 Hacking:美しき策謀―脆弱性攻撃の理論と実際
かなーり、面白い本だった。ノンストップで一気に読んでしまった。
バッファオーバーフロー攻撃などの大まかな原理はわかっていても、実際の攻撃プログラムの実装についてまで考えたことはなかった。この本には短いながらも実際に使える(?)危険なコードが載せられ、丁寧に説明されている。たとえばバッファーオーバフロー攻撃の1つはstrcpyが確保してある配列を超えて書き込むバグを利用するのだが、そのためには送り込むコードにヌル文字(=0x00)が含まれていてはいけない。ヌル文字があるとstrcpyのコピーが途中で止まってしまうからだ。てことで、バイト列に0を含まないようにするために、0をレジスタにロードする命令は 同一レジスタ同士の xor命令に置き換えたりなどのさまざまな工夫を施す必要がある。この本にはそういったテクニックが大量に、丁寧に説明されていて、読んでいて実に楽しい。

コーディング上のテクニックのほかに、暗号の解読方法や、ネットワーク盗聴の方法などにも言及してあって、防衛のためにもこれらに詳しくない人は読んでおくといいんじゃないかなと思った。

ベンフォードの法則

ハッカーのたのしみ―本物のプログラマはいかにして問題を解くか ハッカーのたのしみ―本物のプログラマはいかにして問題を解くか
をやっと読み終えた。素晴らしい本だった。
たとえば符号なしの整数xが2のべき乗であるかどうかを判定するにはどうすればいいか? これは x & (x - 1) という式の結果が0かどうかで判定できる。この式はxの1であるビットのうちで一番右のものを0にするという作用をもつため、2のべき乗のときには結果としてすべてのビットが0になり、そうでないときはいずれかのビットが1のまま残るからである。
また、符号なし32ビット整数nを3で割った商qは、次のようにすれば除算を使わずに乗算とシフト演算だけで計算できる。
q = 0xAAAAAAAB * n / 2^33
0xAAAAAAAB = (2^33 + 1) / 3という数値なので、結果として q = n/3 + n/(3*2^33) を計算しており、さらに2項目が任意の32ビット整数nに対して1/3より小さいことが保証されているからである。
この本にはこの手の一人では思いつくことができないような最適化手法が山のように載っており、コンパイラ作成者やアセンブラでゴリゴリ書く人は必読だろうし、そうでなくても十分楽しめると思う。

で、この本の中に、自然界に現れる数値の先頭桁の分布が偏りについての記述がある。先頭桁が1である確率は1/9でなく約30%にも達し、2では17%に減少、9になるとたったの4.5%しかないという話が載っている。
ググってみると世間ではベンフォードの法則と呼ばれているようだ。この本にはベンフォードの法則の数学的な分析も載っていて、その最初の部分だけ抜粋すると
今、10進数で先頭桁の分布を考えてみよう。そして、「科学的」記法(たとえば6.022*10^23)で表される、長さ、体積、質量、速度などの、単位を持つ数の大きな集合があると仮定する。もし、このような数の集合に属する大きな数の先頭桁が破綻なく定義された分布関数を持っていれば、それはインチやセンチメートル、あるいはポンドやキログラムなどの単位とは独立していなければならない。したがって、その集合の中のすべての数値にどのような定数を掛けても、先頭桁の分布は変化しないはずである。たとえば、2を掛けることを考えると、先頭の桁が1である数値(1.0から1.999...に10の冪を掛けたもの)の個数は、先頭桁が2または3である数値(2.0から3.999...に10の冪を掛けたもの)の個数と等しくならなければならないといえる。なぜなら、長さの単位がインチであるかハーフインチであるか、質量の単位がキログラムであるかハーフキログラムであるかなどは問題になるはずがないからである。
このような考えから分布関数を計算すると、結局のところ先頭桁がDである確率は log(D+1) - logD と計算でき、したがって先頭桁が1の確率は log(2/1) = 0.3010 となる。

実際に下記のURLの末尾のほうに、各種の数値の集合に対してベンフォードの法則に従うか検証した表がある。たしかに綺麗にしたがっていて驚いてしまう。
http://mathworld.wolfram.com/BenfordsLaw.html

こんなに重要な法則を今まで知らなかったのがショックだ。これコーディングのときにも知っておくとおおいに役に立ちそうだなあ。

1/2 >>