2010年03月09日 (火)
卒業旅行
「伊丹 → 成田 → フランクフルト → ヘルシンキ → イバロー → ヘルシンキ → ヨエンスー → ヘルシンキ → フランクフルト → (いまここ) → 成田 → 伊丹」
- オーバーブッキングによりプレミアムエコノミーにグレードアップ.ラッキー
- 機内チャンネルで「パラノーマル・アクティビティ」を観る.帰りは「2012」を見よう.
- フランクフルト空港で,タッチアンドゴー
- 初エアバス機.まぁ基本的に変わらない.カーテンで区切られているだけにしか思えないビジネスクラス席(僕はエコノミー).
- 地方便の搭乗には,チケット不要でIDカード(パスポート)で名前を確認.機内が自由席.飛行機 → ターミナルは徒歩.フィンエアーのシステムにびっくり.
- オーロラは肉眼でようやく確認出来る程度.日本語,日本人.リベンジしたい.
- 全般に料理は悪くない.肉々しくて,ポテトは大量.パンは美味.
- コーヒーが独特の味
- 留学生と再会.右車線.少ない信号.
- 日光で溶けてると滑る.風がなければ意外と寒くない.
- レバーステーキ,サラミヤッキ・ウォッカ.
- 冬の林.樹林.サラミヤッキを大量購入.
- サウナと湖.水風呂ではなく,湖に開けられた穴に,はしごを降りて入る.もちろん氷点下.意外と熱くなく,意外と寒くない.泳ぐ(ただし数十秒が限界).
- ヘルシンキ市内は路面電車(トラム)が発達.
- かもめ食堂.マリメッコ.物欲に襲われるが我慢.食器や家具が欲しい.
- ムーミンショップは,まぁ,イメージ通り.
- だいたいどこでも英語が通じる.もちろん,僕の英語は拙いので苦労はしたが.
- 美術館は月曜日が休日で残念.とはいえ,今回のメンバーはそっち系を好まない.
- フランクフルトの街並みは映画的.
- フィンランドに比べるとドイツの味付けは濃く感じる.
- 本場のビールも苦手気味.やっぱりワインやウォッカのほうが好き.
- ハイデルベルクのお城.ゲームの世界.ICO.
- 度数33%のビールは美味.
- フランクフルトは美味.種類が豊富.
- ザワークラウトは味が濃すぎる.
つづく
2010年01月15日 (金)
crontab を使って効率的にサービス監視する方法
便利すぎるので,早速こことかの生存確認に取り入れた.
# たとえば,ときおり,ImageMagick が更新されたりで止まっている.
余談ですが,getopt では "--" がオプションスキャンの最後だということを割と最近まで知りませんでした.
例えば,以下だと
cronlog -- ping -n 5 my-server 2>&1
cronlog 向けのオプションは無く,-- 以降全てが ping のオプションだということになるわけです.
2009年12月23日 (水)
Sleep Cycle alarm clock が良い感じ。
睡眠の深さを推測して、浅い眠りのタイミングでアラームを鳴らしてくれる目覚ましアプリ。僕でも良い感じに目が覚めてます。
いつまでやってるか分からないセールで115円ですし、良い感じ。最初の数回はキャリブレーションらしいけど、僕の場合は割と最初から良い感じでした。
- ベッドの端に裏向けて iPhone / iPod をおいておくと、寝返りなどの振動を元に、推測してくれる
- 設定時間の30分ぐらい前に鳴ることもある
- サウンドの選択肢が少ない
- 推測結果はグラフとしてみることができる
特徴としてはこんな感じ。
まだ、過去の記録はほとんど無いのですが、使うときがほとんど仮眠のせいか Awake → Deep → Awake → Deep で Dreaming のエリアに滞在していねぇ。どれぐらい正確なんでしょうかw
2009年12月12日 (土)
「募金なう」とTwitterに投稿する募金箱、神戸ルミナリエで
お金が入るとTwitterにつぶやく募金箱らしい。
「ルミナリエ市民ステージでのパフォーマンス」via [塚本研究室 blog!] というのもあるようです。
ルミナリエにいかれる方は、「募金なう」とつぶやかせるのも一興なのではないでしょうか。
2009年12月10日 (木)
2009年11月13日 (金)
golang.org の Language Design FAQ を読みかけた
気晴らしに,辞書を引き引き,読んでいたら対訳してみようという気になったものの,2/3 ぐらいで力尽きてしまい,一番面白そうなところ(Concurrency)まで進めなかった.
せっかくなので,アップしておきます → Language Design FAQ @ golang.org の適当訳.
言語仕様も追いかけながらじゃないと理解の追いつかない部分があるなぁ.
2009年11月10日 (火)
モチベーション
つまるところ,最近の悩みはここである.モチベーションの源泉はいったい何なのか?
自分がなぜ,ものを作りたいのか?というのは脳みそがバラバラに解体されない限りは,分からないんじゃないかなぁと思う.自尊心なのか,形を変えた種の保存なのか,好奇心なのか,使命感なのか,はたまた全く別物なのか.ただ単に,ものを作る集団の生存確率が高かったための,遺伝形質だという答えが出そうな気はしている.結局のところは,観測問題なんだろう.
とはいえ,嘯いたところで何も前進しないので,自問を繰り返さざるを得ない問題である.研究していたり,irodori に参加していたり,ゲームしていたりすると自然にわき上がる疑問.いまだに答えを出すことができないし,これからも出せないとは思う.
モチベーションが高くても,微妙にミスマッチングして,逃避は止められない. はたして,いつか「面白いから」「好きだから」ではない,説明を持ち得るのだろうか. 悩んでる暇が有れば,手を動かし続けた方が有意義だと, 自分をだましだまし,とりあえず,目先の欲望に素直に生きている.
2009年11月06日 (金)
浮動小数点(IEEE 754, 32bit 単精度)について
- ループの終了条件に小数を指定するのは避けるべき [王様の箱庭]
- 私もうfloatくんのこと…信じられない…! [王様の箱庭]
を受けて書いてみた.
C 言語の float は IEEE 754 準拠だと明記されていないのですが,基本的には IEEE 754 形式だと思っていいはずなので,IEEE 754 基準で調べたら OK です.
IEEE 754 では,32bit の 2 進数で小数を表現するために,内部を「符号,指数部,仮数部」に分けています.それぞれが「1bit, 8bit, 23bit」です.
基本的に IEEE 754 - Wikipedia などを読めば分かるのですが,理解の確認のために再整理.詳しいことはパタヘネ辺りを読めばいいと思います.後で参照して補足します.
2進数は,小数点でどうやって表現されているか
浮動小数点 と 固定小数点 の2通りがありますが,ここでは浮動小数点のみを扱います.なお,固定小数点は,ある桁に小数点があるものと見なす(例えば,256 倍しておく)ものです.
32bit の 浮動小数点数 は,基本的には,以下の数式で表現できます( ^ は累乗).この形式で表現できるのは正規化数です.例外は後述.
(-1) ^ (符号) * (1.仮数部) * 2 ^ (指数部-127)
符号部
これは単純に 0 なら 正,1 なら 負 です.整数の 2 の補数表現とあわされています.
仮数部
小数を IEEE 754 形式に表現し直す際に, 1.XXXX * 2^exp という形に直します.これを正規化といいます.仮数部には 1. の下の小数部である XXXX のみを持ちます.
は説明がわかりにくいですが,2.5 であれば(十進数を xxx (10),二進数を xxx (2) と表すこととすると),
2.5 (10) = 10.1 (2) * 2^0 = 1.01 (2) * 2^1
と正規化され 0.25 (10) = 0.01 (2) となりますので,仮数部は 01 となります.残りの 21 bit は 0 で埋めます.
指数部
指数部は 「指数 + 127」 の値を格納します.なぜ,2 の補数を使わないかというと,(正規化数の)浮動小数点数の大小比較を簡単にするためです(混乱中ですが,たぶん後述).すなわち,8bit の 0 〜 255 で -127〜128 を表現します.先ほどと同様に,Wikipedia の例をパクってくると, 2^1 は指数部に 128 として表現されます.
よって,2.5 (10) = (-1)^0 * 1.01(2) * 2^1 は 0_1000,0000_0100,0000,0000,0000,0000,000 として,表現されます(コンマは手前から 4 桁区切りでつけているだけです).
irb で確認
「packテンプレート文字列 - Rubyリファレンスマニュアル」によると,IEEE 754 準拠な環境なら簡単に変換結果を確認できるようです.
> [2.5].pack("g").unpack("B*")[0][0,32]
=> "01000000001000000000000000000000"
# 符号
> [2.5].pack("g").unpack("B*")[0][0,1]
=> "0"
# 指数部
> [2.5].pack("g").unpack("B*")[0][1,8]
=> "10000000"
# 仮数部
> [2.5].pack("g").unpack("B*")[0][9,23]
=> "01000000000000000000000"
確かにうまくいっています.
16777216.0, 16777217.0, 16777215.0 はどうなるのか?
16777216.0 (10) = 1.0 (2) * 2^24 ですので,符号は 0,指数部は 24+127,仮数部は 0 となりますね.
一方,16777217.0 (10) = (1.0 + 2^(-24) ) (2) * 2^24 ですので,2^(-24) を表現するには仮数部が 1 bit 足りず(23bit では 2^(-1) 〜 2^(-23) まで),丸められることとなります.
16777218.0 (10) だと (1.0 + 2^(-23) ) (2) * 2^24 ですので,23bit にぎりぎり収まるため,float で表現可能になります.
irb で確認してみると,確かに,16777216.0 == 16777217.0 != 16777218.0 となっていますね.
> [16777216].pack("g").unpack("B*")[0][0,32] # 仮数部は 00000000000000000000000
=> "01001011100000000000000000000000"
> [16777217].pack("g").unpack("B*")[0][0,32] # 仮数部は 00000000000000000000000
=> "01001011100000000000000000000000"
> [16777218].pack("g").unpack("B*")[0][0,32] # 仮数部は 00000000000000000000001
=> "01001011100000000000000000000001"
すなわち,float だと 16777216 = 2^24 以上では,2.0 未満の違いを表現できなくなります不正確なので削除.double だと,仮数部の bit 数が増えるので,今回の数は全て表現可能です.
16777215.0 になると,今度は指数部が 1 小さくなりますので,仮数部において 1.0 が 2^(-23) * 2^23 と表現できるようになり,丸めが発生しません.
# 1 違いが大きな違いに
> [16777215].pack("g").unpack("B*")[0][0,32]
=> "01001011011111111111111111111111"
> [16777216].pack("g").unpack("B*")[0][0,32]
=> "01001011100000000000000000000000"
# 16777215 と 16777216 との指数部の比較をしてみると,1 異なる
> [16777215].pack("g").unpack("B*")[0][1,8]
=> "10010110"
> [16777216].pack("g").unpack("B*")[0][1,8]
=> "10010111"
0.1 について
0.1 というのは,2進数の浮動小数点表記において,正確に表現することができないかずです.直感的には,そんな馬鹿な!と言いそうになるのですが, 2^n をどう足し合わせても 0.1 ちょっきりにはなりません(0.1 = 1 / 2 * 1 / 5 ですが,5 は素数のため,1/5 は m/2^n では表すことができません).
では 0.1 がどう表現されるかというと,正規化すると 16 倍して 1 を超えるので,指数部は -4 となり
0.1 * 16 (10) = 1.6 * 2^(-4) (10)
仮数部は 0.6 ≒ 1/2 + 1/16 + 1/32 + ... (= 0.5 + 0.0625 + 0.03125 + ...) であり,実際に irb で確認してみると(厳密には 0.1 0110 0110 0110 ... と 0110 が繰り返す循環小数となるはずです)
> [0.1].pack("g").unpack("B*")[0][0,1]
=> "0"
> [0.1].pack("g").unpack("B*")[0][1,8]
=> "01111011"
> [0.1].pack("g").unpack("B*")[0][9,23]
=> "10011001100110011001101"
こちらは,bit 数不足の問題ではないので,double でも回避できない本質的な表現能力の問題です.3進数では正確に表現できる 1/3 を 10進数 では循環小数としてしか表現できないのと同じことです.
後,たぶん,一般にループの終端条件に小数を用いる場合は許容誤差込みで大小判定します.while (f != 10.0) ではなく while (10.0 - error <= f && f <= 10.0 + error) のようにするのではないかと思います.たぶんね.
非正規化数について
余力が有れば追記.
大小比較について(整理中)
というのも,正規化されていれば, (-1)^符号 * 1.仮数部 * 2^(指数部+127) と表現されますので,「符号,指数部,仮数部」と並べておくことで,大小比較が簡単になるはずです.
例えば,lhs と rhs の大小を比べる際には,
lhs, rhs の双方が正
- どちらかの指数部が大きい → 指数部の大きい数が大きい(∵正規化されているので)
- 指数部が等しい → 仮数部のより大きい数が大きい
これは,正の整数同士の比較において,上位桁が大きいほど大きいということで正しく判断できる.
lhs, rhs のいずれかが負
- 2の補数表現では最上位ビットが 1 だと負であり,「正の数 > 負の数」として正しく判断できる.
lhs, rhs の双方が負
- どちらかの指数部が大きい → 指数部の大きい数が小さい
- 指数部が等しい → 仮数部のより大きい数が大きい
こちらは 2 の補数表現同士の比較と一致しない・・・でいいんだっけ?


