憂鬱な午後のひととき


7月28日_
口内炎が酷くて頭もがんがんする. バファリン飲んでもあんまし効かない. 鏡で見たら5mm大のものが二つもある. これはすぐには治りそうにないなあ.
7月27日_
連日のあまりの暑さでへたり気味. で, 週末も先月から始めたProject Eulerをだらだらやってた. 自分にはとっても厳しいHaskell縛り. で, どうにか100問到達. C++なら富豪的にできそうなものHaskellじゃそうはいかないことも多かった. リスト内包表記は便利. 高階関数やモナドはまあ言われてるほど何か特別で高尚なもんというわけじゃない. 数学的には素直な概念だし. それよか標準のArrayの更新がO(n)といった, 副作用が無いことによるデータ構造のしばりがきつかったり, 遅延評価+リストがよー分からん(ケースバイケースでいちいち検討なんてしてられない)時間オーダーになったりの方が遥に落とし穴, と感じた. ま, あくまで計算主体の問題しか解いてない上での所感やけど神様言語か何かと思ってたのがそうじゃなかったと分かってよかった.
7月23日_
朝会社で一人のときにうっかりカードキーを忘れてトイレに行ってしまった. 財布も携帯電話も無くてどうしようもない. 幸い15分ほど待つだけで事務の人が来たので入れたけど, その人が休みだったら1時間は待たんといかんかった. 危ない. 危ない.
7月19日_
「floatやdoubleの16進表記が欲しい時」はunionとか%llxじゃなくて(C99以降 or VC++なら)%aをつかえばいいんですよ.
printf("%.13a\n", 0.1);
>0x1.999999999999ap-4
7月17日_
肩凝りが酷いのでマッサージに行ってみた. 5000円. 凝りすぎてちょっとずつしないとほぐせないらしい. 高いんだけどしばらく通うべきか. 今はもみかえしとかで全身だるい.
7月15日_
浮動小数点数のちょっとしたクイズ
WEB+DB PRESS Vol.57のPHPでの記事で浮動小数点数の話があった. 0.1を10回足しても1にならないというよくあるやつ. 本では0.1は0.10000000000000001に, sumは0.99999999999999989になるという. 今までも見て素通りしてたけど今回は気になってCでも同じかと試してみた.
#include <stdio.h>

int main()
{
    double x = 0.1;
    printf("%.17f\n", x);
    double sum = 0;
    for (int i = 0; i < 10; i++) {
        sum += x;
    }
    printf("%.17f\n", sum);
}
>0.10000000000000001
>0.99999999999999989
同じだ(Pythonでも同じだった). 0.1は2進数表記で無限小数になるので大きいほうに丸められて0.10000000000000001になるのはいいとして, 0.1より大きいものを10回足したのに, なぜ1を超えないのだろう. 少し考えるとすぐわかるのだけど, でもパッと見は不思議だ.
7月14日_
・空の雲が大分夏っぽくなってきた.
宝くじ、当選4回で計19億円
1.8x1025分の1の確率らしい. コップ1杯(180g)の水の中に水分子は6x1024個だからコップ3杯分の中から1個のH2Oを当てる確率. あるいは1光年=9.4x1015mだから, 直径1mのボールを宇宙の端から(137億光年?)端まで並べたところから一つ当てる確率. どちらにしてもピンと来ない.
7月13日_
ペアリングフォーラム参加
私もぼちぼち昔作ったアプリを最近のペアリングに置き換えてきちんと作り直したいな.
7月11日_
高階関数クイズ
最初twiceは2倍する関数かと思ったけど
twice twice twice twice add1 0
のtwiceが作用する空間はそれぞれ違うんだなあ. 空間XからXへの写像全体をM(X)として, 上記コードをそれぞれのtwiceを区別するためにt''' t'' t' t a 0と略記するとt∈M2(X), t'∈M3(X), t''∈M4(X), t'''∈M5(X).

t' t a = t(t(a)) = t(aa) = aaaa = a4

t'' t' t a = (t4)(a) = (t3)(a2) = (t2)(a4) = t(a8) = a16

t''' t'' t' t a = (t16)(a) = (t15)(a2) = (t14)(a^(22)) = (t13)(a^(23)) = ... = a^(216)

7月10日_
頭と肩が痛くて完全にへたってたのでジブリの映画立て続けに見た後更にぽけっとテレビを見る. 『ピタゴラスイッチ』という番組がなかなかおもろい. ピタゴラ装置みたいなのは小さいときよう作ったなあ. 番組中に「テレビのジョン」というキャラクターが出てきたが形がどうみてもアナログテレビ. 来年は「地デジのジョン」となって薄くなったりするのだろうか.
7月8日_
私は英語さっぱりなので社内公用語と言われたら反対意見を出すだろうなあ. もし説得されたらせっかくの機会だし勉強してみようと思うかもしれない. 強制度合いによっては別の方法を考えるか悩むかもしれない. その辺は愛社精神の度合いにもよるだろう.

ところで, 下手な英語だと馬鹿にする人が多いのに驚いた. そういう人は日本語を母国語としない人が下手な日本語をしゃべったら同様のことをするのだろうか.

ちゃんとしゃべれないと話しちゃいけない気持ちを持たせるのが日本の英語教育の悪い点な気がする. 少なくとも, 学校で習ったのは「正解」だけだった. 伝わらなかったら別の方法で言ってみよう, もっぺん言ってみようと教えてもらった記憶はない. 教科書的正しい答えでしゃべろうとして考えてる間に結果的に黙り込んでしまうことになる(自分は).

何度か一対一で英語でしゃべらないといけない場面になったときは, 本当に文法も発音もめちゃめちゃだったけど, 繰り返して紙と鉛筆も使っていればある程度は伝わった(まあ両者エンジニアだったからというのもあるけどね). そんとき, ああそういうもんか(伝えるのが最優先なんだよ)と開き直れた(結果, 上達意欲が薄れた…えっ). まあ, そんな意図も入ってるなら公用語もありかも. んー, でもやっぱり悩むな.

7月7日_
『数学のおもしろさ(対話 20世紀数学の飛翔)』(斉藤恭司 志賀浩二)
n_shuyoさんに貸していただいた. たまたま数日前にモンスター群と楕円モジュラーの話ってきちんと勉強してみたいなあという会話をしていたところなので 斉藤先生の口調がリアルに再現されてなんかもう普通に読めない. 僣越ながら「そうだよなー」と思わずうなずいてしまうところも多々あって面白かった(特に(公理論的なところは)その道の人に任せて自分は目の前の数学をするというところとか).
7月6日_
RIP相対
実際遅いのかなと試してみた. 試していてXbyakのバグを見つけた(--;
struct Test1 : public Xbyak::CodeGenerator {
    explicit Test1(int lp)
    {
        for (int i = 0; i < lp; i++) {
            Xbyak::util::setEipTo(this, eax);
        }
        ret();
    }
    int (*get() const)() { return (int (*)())getCode(); }
};

struct Test2 : public Xbyak::CodeGenerator {
    explicit Test2(int lp)
    {
        for (int i = 0; i < lp; i++) {
            call("@f");
        L("@@");
            pop(eax);
        }
        ret();
    }
    int (*get() const)() { return (int (*)())getCode(); }
};
ベンチマーク
rip bench[unit:clk]
call func[lp=1] call + pop[lp=1] call func[lp=10] call + pop[lp=10]
Core2Duo 10.01 14.00 4.70 3.30
Core i7 23.55 14.00 11.00 5.15
Opteron 14.24 11.59 9.56 4.76
最初lp=1のときだけやって, ありゃ, i7とOpteronだとcall + popの方が速いよと思ったので連続呼び出しも試してみた. やっぱりcall + popの方が速かった. いやまあ, eip取得を連続呼び出ししたり, 関数呼び出してeipだけ取得したりすることにどこまで意味があるのかわからんけど(こんなけ連続callされたらCPUも困るだろう).
7月5日_
こわいはなし
>実は 20 段くらいネストしてるから空白だけで 80 column 越えしてたのだった。
レイアウト系では
                           ...
                               for (...) {
                                 for (...) {
                                    a +=
                                    b
                                    * c;
                                    d =
                                    f(a,
                                     b)
                                    + e;
                                    ...
的なのをみたことがある. なんで式の途中でそんなに改行するねんと思ったら, 深いネストと80カラム制約とを両立させるために編み出された答えだったっぽい. 殆ど縦書きである.
ロジック系では
int func(int a)
{
    if (a <= -32768) a += 65536;
    if (a >= 8192) a -= 8192;
    if (a >= 4096) a -= 4096;
    if (a >= 256) a -= 256;
    if (a >= 8) a -= 8;
    if (a >= 4) a -= 4;
    if (a >= 2) a -= 2;
    if (a == 0) {
        return 1;
    } else {
        return 0;
    }
}
みたいなの. ファイル属性が読み出し専用か(何か)調べたかったらしい. 要は(a & 1) == 0なんだが, 各数値は多分システムヘッダを調べたんだろうなあ.
7月4日_
第1回 自然言語処理勉強会行ってみた. 当日の朝までキャンセル待ちが決まらずやきもきした. shuyoさんのエンジニアと研究者の視点の違いの話が面白かった.
7月3日_
NHKの白熱教室のカントの回を見る. 良いように見られれようと行動するのと良いように行動するのとの差ってどんなもんかな. 同時に読んでた『哲学ってなんだ』(竹田青嗣)の, カントを批判したというヘーゲルの考え方が自分には腑に落ちた.

人間は生まれつき「自由」なのでもなく, 「自由」であるべきというのとも違う. 少しでもより「自由」たろうとする本性を持っている. 「自由への探求」が本質.

7月2日_
kikxさんにつっこんでいただいた.
下はちょっと安直に考えすぎたか.
7月1日_
RはQ上無限次元ベクトル空間
f(x + y) = f(x) + f(y) for x, y∈R → ∃λ∈R, st. f(x) = λxはfがLebesqueルベーグ可積分だったら言えたんだっけか. 遙か昔, 演義でやったような.

fが可測なので∫01f(x + y)dx = ∫01f(x)dx + ∫01f(y)dx = ∫01f(x)dx + f(y). よってf(y) = ∫01f(x + y)dx - ∫01f(x)dx.

ここでy→0のときf(y)→0を言いたい(一点でも連続が言えれば後は簡単).y→0のときf(x + y)→f(x)だから積分と極限操作の順序を入れ換えられればOK. Fubiniの定理を使うんだっけ. 仮定はなんだっけか. ある可測関数で|f(x + y)|を抑えられることだったかな. [0, 1]区間で有界ぐらいの条件がいるのかな. 実家にある本かノートを見たい. うーん, kikxさんのつっこみを期待しよう.

FubiniじゃなくてLebesqueの定理だったか

御意見は光成滋生<herumi@nifty.com>までお願いします