スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

始まりはいつもゼロ? - 0オリジンと1オリジン

ポーランドの大数学者、ヴァツワフ・シェルピンスキーは・・・荷物を一つなくしてしまったのではないかと心配していた。「そんなことないわよ、あなた!」と妻は言った。「六つともここにあるじゃないの」。 「そんなはずないよ」とシェルピンスキーは言った。 「何度も数えたんだ。ゼロ、1、2、3、4、5」
415208524X今でこそ私たちの生活に入り込み、普通に使われている0(ゼロ)。しかし、中世まで0は当たり前の存在ではなく、むしろ忌むべきものとして排斥の対象ですらありました。アリストテレスを戦慄させ、近代科学の祖デカルトが否定し、天才アインシュタインが挑んだゼロ。。。最近読んだ「異端の数ゼロ―数学・物理学が恐れるもっとも危険な概念」という本は、ゼロが数学・物理学・宗教・哲学の歴史の中でどのように扱われてきたかについて書かれており、非常に面白かったです。この手のポピュラー・サイエンスものが好きな方にはお勧めです。古代ギリシャでは数学が幾何学と密接に関連していたために0がなかった話など、なるほどという話がたくさんありました。

さて、身の周りには0から始るものと1から始まるものが混在しています。西暦は1年から。西暦0年はありません。西暦1年の一年前は紀元前1年です。カレンダーで言えば月や日も1から。でも時間は0から。年齢は数え年は1から、満年齢は0から。ものを数える時は1からですが、カウントダウンは0で終わる。。。それぞれに歴史的経緯や意味が隠れています。。

プログラミングにおいても同様の問題が顔を出します。0オリジン/1オリジン(0 origin/1 origin)や0基準/1基準(0 base/1 base)と呼ばれているものです。最も分かりやすい例は配列の添え字でしょう。C言語系の言語(C++やJava)では配列の最初の要素はa[0]と書きます。FORTRANやCOBOL、BASICではa[1]と書きます。何番目の要素という意味合いを考えれば、添字は1オリジンが自然な気もします。しかし、C言語系の言語では、配列はポインタと強く結びついているために、a[0]は「aの0番目」というよりは「先頭からオフセット0の要素」「*(a + 0)」いう意味合いになっています(※1)。

最近は、C言語系の言語が主流なので、大抵のプログラマは0オリジンの頭になっているでしょう。私も1オリジンのプログラムを見て、「何だこれは」と感じたことはあります。この0オリジン/1オリジンの問題は、混在させると非常にややこしくなるので、少なくともプロジェクト単位くらいでは統一するようにした方が心の平穏を保つためには重要です。

私は大勢と同様、0オリジンが好きですが、最近は1オリジンも見直しています。見逃されがちですが1オリジンのメリットは0を使わない点にあります。よく変数を見初期化のまま仕様して0が入ったりすることがありますが、このように偶然入る0を0オリジンの場合はそのまま使用してしまいますが、1オリジンでは不正規な値として弾くことができます。偶然の動作を防ぐというのはデバッグ効率を考えると非常に重要な点です(参考:バグを潜伏させない工夫)。この点を考えると、1オリジンも捨てたものではないなと思う今日この頃です。

ちなみに、プログラミングにおける0は、0除算(zero devide)やヌルポインタ(null pointer)等、特殊な意味合いを持っています。

※1 C言語ではa[-1]も*(a-1)という意味になり、文法的に間違いではありません。

【関連記事】
バグを潜伏させない工夫
デバッグ指向のススメ

【関連書籍】
異端の数ゼロ―数学・物理学が恐れるもっとも危険な概念 Charles Seife
数の本 J.H. コンウェイ R.K. ガイ
零の発見―数学の生い立ち 吉田洋一
プログラミング言語C ANSI規格準拠
スポンサーサイト

共感覚 - 色の音・香りの形

目を閉じよ。そしたらお前は見えるだろう。
サムエル・バトラー
耳に聴こえるメロディーは美しい。だが聴こえないメロディーはさらに美しい。
ジョン・キーツ

共感覚という言葉をご存知ですか?ある刺激を受けたとき、本来の感覚に他の感覚が伴って生ずる現象を指す言葉です。印刷された言葉や数字が色となって感じられたり、香りが形を伴ったり、話し言葉が虹色に見えたり。。。単なる連想記憶とはまた違って、刺激を直接複数の感覚として感じる現象のことです。誰しも赤ちゃんの時には共感覚を持っているものの、成長と共に失われるという説もあるそうです。
私自身はたまたま立ち寄ったブログ(小さな哲学~雑草の世界)で知ったのですが、これを見て最近TV番組で見た、色を音で認識する機械をつけた美大生の話を思い出しましたので紹介したいと思います。

アイボーグその青年、Neil Harbissonは重度の色覚障害のため、全てが白黒の世界で生活していました。しかし、アイ・ボーグ(Eye-Borg)と呼ばれる機械によって彼の世界は豊かな色を取り戻します。彼に色を取り戻させたアイ・ボーグは、色を音に変換する装置です。具体的には、色に応じた音を発生させるのです。赤なら低い音、青なら高い音。彼は、この機械によって、色を認識することができるようになり、色彩豊かな絵を書けるようになったのです。(BBCの参考記事)

この「色を音で感じる」というのは魅力的な響きを持っており、何となくロマンチックなイメージを掻き立てもします。さわやかな色に静かな音楽、鮮やかな色彩に賑やかな音楽。。。しかし、実際のアイ・ボーグを通じて色を見た時に耳に届く音は、無機質な電子音でしかありません。そこには、私たちが美しいと感じる音色はありません。

感覚というのは主観的なものです。同じ刺激に対して、誰しもが同じように感じているという保障はありません。実際、人によって美しいと感じる基準は異なります。見方を変えれば、あるものを美しいという感じるための刺激が、人によって異なるというようにも考えられます。そう考えれば、先のアイ・ボーグの場合、私たちにとっては無機質な電子音にすぎないアイ・ボーグが生成する音も、Neilさんにとっては豊かな色彩となって知覚されているのでしょう。

考えても見れば目で色を感じるのも所詮は脳に届けられる段階では所詮ただの電気刺激。舌で物を見ようという研究もあるくらいです(参考:舌で物が見えるようにする感覚代行器具)。ただ、このような特殊な感覚に対しては、どうしても人とは違う感性をもっているんだろうなという眼で見てしまいがちです。

しかし、これらの話を知って思ったのは、最初の共感覚にせよ、アイ・ボーグの話にせよ、どのような形で知覚するかといのは実はあまり重要ではないのではということ。「どうやって感じるか」ではなく「何を感じるか」。HOWではなくWAHT。最後の最後、心で感じているイメージは誰しも変わらないのではないでしょうか。

【関連リンク】
4873112710Seeing things in a different light (BBC)
共感覚 (小さな哲学~雑草の世界)
ママの声って何色 (asahi.com)
言葉や音に色が見える――共感覚の世界
N2's Homepage! 共感覚
舌で物が見えるようにする感覚代行器具

【関連書籍】
ユーザーイリュージョン―意識という幻想 Tor Norretranders
ねこは青、子ねこは黄緑―共感覚者が自ら語る不思議な世界
共感覚者の驚くべき日常―形を味わう人、色を聴く人
奇跡の人 ヘレン・ケラー自伝

使用しない仮引数

多くを知るものは少なく語る
Who knows most says least.
仮想関数やテンプレート関数等、同じシンタックスで複数の使われ方をするような関数では、使用しない仮引数というものが登場することがあります。例えば、
class ClassBase {
  virtual func(int hint);
};

class ClassA : pulic ClassBase {
  virtual func(int hint);
};

void
ClassA::func(int hint)
{
  // このClassのfuncでは仮引数hintは不要なので使用しない
  ...
}
仮想関数やテンプレート以外でも、関数仕様として拡張性を持たせるために用意されているものの、現状では使用しない場合等も考えられるでしょう。

さて、このような使用しない仮引数が使用しないだけで、動作上問題はないのですが、コンパイル時に未使用変数(unused variable)として警告目セージが出力されてしまいます。このような警告を出力されたままで放置すると、本来注意するべき警告が埋もれてしまう(見逃されてしまう)可能性もありますので、できれば避けたいところです。
ここでは、このような未使用仮引数の警告を抑制するいくつかの方法を紹介します。

■コンパイラのunused属性を使用する
コンパイラによっては、変数や構造体に属性をしているための方法が用意されています。例えば、gccでは次のような指定が可能です。
void
func(int val __attribute__ ((unused)) )
{
 ...
}
(参考)GCC - 変数属性の指定

unused以外では、構造体のパック(pack)やアライメント(alignment)調整等、セクション配置等が指定できます。
この方法の問題は、指定方法がコンパイラ依存のため、移植性に問題がでる点です。

■仮引数名を省略する
Cでもプロトタイプ宣言中では仮引数名を省略できましたが、C++では関数定義でも省略できます。使用しない仮引数は、変数名を省略することで、その仮引数を使用しないということをコンパイラに伝えることができます。
残念ながらこの方法はCでは使えません。

■voidキャストを使う
この方法が個人的には最もおすすめです。使用しない変数を関数定義中でvoidキャストしてやる方法です。例をあげます。
#define UNUSED_VARIABLE(x) (void)(x)

void
func(int val)
{
 UNUSED_VARIABLE(x);
 ...
}
この方法のメリットは、C,C++共通で使える、移植性の問題もない、といったこともありますが、何よりあとから未使用変数をgrepし易いこと点があります。上記の例では、未使用変数宣言用のマクロを用意して使用していますので、ソースコード中からUNUSED_VARIABLEをgrepすることで、未使用変数を洗い出して見直すことができます。

【関連記事】
warningに気を配る

【関連リンク】
仮引数名の省略 (C++と組み込み環境)
GCC - 変数属性の指定

【参考書籍】
GCC GNU C Compiler―Manual & Reference
Introduction To Gcc (Richard M. Stallman)

フェルミのパラドックス

この世にはわれわれだけだと思うこともあるし、そうではないと思うこともある。いずれにせよ、そういうことを考えるところがすごいことだ。

宇宙の歴史は長く、そうして宇宙は限りなく広い。とすれば、地球外にも知的生命体(ETC)は存在するはずだ。でも、その気配はない。「みんなどこにいるのか?」二十世紀最高の天才物理学者エリンコ・フェルミは問いました。

479176126X 最近読んだ「広い宇宙に地球人しか見当たらない50の理由―フェルミのパラドックス」は、この「フェルミのパラドックス」について書かれた本です。本書のあとがきにもありますが、宇宙人がいる、いないという話になると、「いないはずがない」「いるはずがない」という二者択一論になりがちです。勿論、いるかいないかのどちらかしかないのですが、そういってしまうと議論が終わってしまいます。本書は「はずがない」ではなく「なぜそうなるのか」をいろんな観点、宇宙論から物理学・生物学・数学から社会学・SF的発想までを総動員して、その理由について科学的に検証しており、知的好奇心を刺激する一冊でした。

私自身は「地球や人類が特別と考えるのはおかしい。宇宙は限りなく広いんだから、他にも知的生命体はいるはずだ。(地球に来ているとかいうのは別にして)」という考えでした。いわゆる平凡原理というやつです。しかし、実際宇宙は「限りなく」広いわけではなく有限です。時間的にも空間的にも(勿論、現在の宇宙論が正しいとしてですが)。よって、ETCの発生確率が、宇宙の大きさを相殺して余りあるほど低ければ、ETCが地球外に存在しないと考えるのが自然です。雨の中を走って、一滴の雨粒にもあたらない可能性も0ではないでしょうが、事実上0です。では、ETCの発生確率はどれくらいなのでしょうか。

宇宙の大きさといった規模になると、ついついその大きさに圧倒されて、考えることを放棄してしまいがちです。しかし、既存の理論や知識でも、それらを丁寧に積み重ねていけば、ある程度妥当な推論を導けることがあります。宇宙の神秘に思いを巡らす時もそうですが、仕事における工数見積もり等でも、似たようなことは言えるかもしれません(^^;)。

その他、この本の中では、フェルミ推定やデルタt論法などの考え方、なるほどといった論理の展開方法等も紹介されており面白いです。

【関連レビュー】
情報考学 Passion For The Future
Amazon

【関連書籍】
宇宙に隣人はいるのか ポール・デイヴィス
もしも月がなかったら―ありえたかもしれない地球への10の旅 ニール.F.カミンズ
奇妙な論理〈1〉―だまされやすさの研究 マーティン・ガードナー
人はなぜエセ科学に騙されるのか カール・セーガン

warningに気を配る

忠告には用心せよ。この忠告に対してもだ。
Beware of advice - even this.

プログラムを組んでいるとどうしてもちょっとしたミスタイプをしてしまいます。変数名や関数名の間違いのようなものであれば、コンパイルエラーになってすぐ修正すれば終わりです。しかし、中にはコンパイルが通ってしまうというものもあり、実行時にバグを引き起こしてしまうことがあります。

例えば、よくある==と=の間違い。
if (flag = 1) {
  ...
}
val = 1は1を返す式として評価されるので、C/C++上の文法は満たしていますが、大抵の場合、これは、「flag == 1」の間違いでしょう。 これは、普段から「1 == flag」と定数値の方を左辺に持ってくるくせをつけているとある程度防げます。とはいえ、この方法は両辺が変数であったりすると使えないのと、可読性が低くなりがちなので敬遠されることもあります。

もうひとつよくあるミスタイプ別の例をあげると、switch分のdefaultのタイプミスです。
switch (char_type) {
case ALPHA:
  printf("this is alphavet\n");
  break;
case NUM:
  printf("this is numeric\n");
  break;
defualt:
  printf("this is unknown character\n");
  break;
}
defaultとかくべきところをdefualtと書いてしまっています。一見、コンパイルエラーになりそうな気もしますが、実際は、defualtはラベルとして認識されるため文法的にはエラーになりません。もちろん、動作は期待通りにはいきませんので、当然バグになります。

さて、これらのちょっとしたスペルミスはよくあるバグの原因ではありますが、コンパイラのwarningをチェックしていれば大抵気付くようなものです。大抵のコンパイラであれば、上記のような記述は文法的には正しいとは言え、ミスタイプの可能性が高いものとしてwarningを出してくれます。よって、コンパイル時にwarningに気を使うくせをつけておけば、すぐに修正して終わるようなものなのです。

プロジェクトによっては、コーディング規約で全てのwarningをなくすようにというところもあると思いますが、そうでなくても、普段からコンパイラからの警告には耳を傾けるようにしましょう。

【関連記事】
使用しない仮引数

【関連リンク】
C/C++バグ防止: defaultのスペルミスに気をつけろ!
明解プログラミングのすすめ (Cプログラミングの秘訣)

【関連書籍】
ライティングソリッドコード―バグのないプログラミングを目指して スティーブ・マグワイア
C++プログラミングの処方箋―ひと味違うコードを書くための99の鉄則
プログラミング作法 ブライアン・カーニハン
人気エントリ
最近の記事
本のおすすめ

4274065979

4844337858

482228493X

4904807057

4873114799


最近のコメント
Links
プロフィール
  • Author:proger
  • 組み込み関係で仕事してます
ブログ内検索
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。