JavaScriptは0.1 + 0.2を計算できない

今日、大いにはまった。

alert( 0.1 + 0.2 );

の結果は、

0.30000000000000004

となる。これは0.1と0.2の組み合わせだけに起こる奇怪な現象という訳ではなくて、「0.9 * 0.1」とか「0.28 * 10」とかでも同様の現象が発生する。またIEFireFoxOperaNetscapeといった主要ブラウザ(Safariが手元にないのでどなたかやってみて下さい)が揃って同じ挙動だ。ということはECMA Scriptとしての仕様なのかと感じられる。
例えば、Javaのプリミティブでもdoubleで持てないような桁の場合はまるめられてしまったりする訳だけど、まさか「0.1 + 0.2」が計算できないとは思ってもみなかった。

[追記]
Javaの例が悪かったので追記。

public class Test {
public static void main (String[] args) {
System.out.println((float)0.1 + (float)0.2);
}
}

Javaの場合は型が明示的に存在する言語なので、上記のようにすると0.3になる。
やり口的には

System.out.println((double)0.1 + (double)0.2);

も出来ると思うけれど、OSの制度が64bitまでないと無理かと思う。

[追記 2]

alert( parseFloat(0.1) + parseFloat(0.2) );

も駄目だった。うーん。整数に戻したあとに、割り算するしかないのかなぁ。

IE7でもCSSのexpressionが利用可能

下位互換か需要の必要性があってか、IE7でもCSSのexpressionが使える。このexpressionというのはJavaScriptが書けてしまうので、XSSの事例とかでよく題材にされる。以下のページに解かり易く書いてある。
WebAppSec – WebAppSec Wiki – IEのexpressionとurl
最新のIE6とIE7では、url内にJavaScriptを書いても反応しないようだけど、expressionは使える。XSSの話は置いておいたとしても、どういう場面で効果的なんだろうか。いまいち使い方が想像できない。

php.ini-recommendedはデフォルトでmagic_quotes_gpc=Off

「サニタイズ言うなキャンペーン」私の解釈
高木さんのブクマから発見したページ。とても解り易い説明だと思う。
PHPの話だけど、PHPのインストール時によくphp.iniの元ネタとして使われるphp.ini-distは

magic_quotes_gpc = On

が初期設定になっている。ところが、php.ini-recommendedだと

magic_quotes_gpc = Off

となっている(PHP 5.2.0)。だから、本来はPHPも「magic quoteをOffにするべきなんだよ」と考えているのかななんて思う。
でも、ホスティングなんかだとmagic quoteがOnのことが多いと思うし、汎用的にするためにmagic quoteがOnでもOffでも動作するようにしましょう的なことを書いているページも見かけるので、PHPのmagic quoteの設定はいつまで経っても困惑しそうなことだなと感じてしまう。

iTunesのディレクトリをアルバム単位にする

ネットワークから見るなどはiTunesをクライアントにしないないことが多いので、iTunesが整理するディレクトリの分け方(アーティスト単位)があまりにも判り難くかった。そこで、アルバム単位にディレクトリを分けるように変更してみた。と言っても、iTunesにそんな気の利いたオプションがある訳ではなさそうなので、思い切って全てをコンピレーションにしてみた。
思い切ってやっただけあって、「コンピレーション」ディレクトリ配下には全てのアルバムがずらっと並んだ。デメリットとしては、洋楽でありがちな「The Best」というようなアルバム名重複が発生すると、同じディレクトリ内にまとめられてしまう。それでも、前よりは断然に探しやすくなった。
普通のアーティストアルバムが多い人だと、デフォルトでもそれなりに綺麗に配置されると思うけれど、サウンドトラックとか、まとめアルバムとかを多く持っている人にはおすすめかもしれない。

Firefoxでz-indexを使うとフォームのカーソルが描画されなくなる問題

<html>
<head>
<style type="text/css">
#back {
position: absolute;
top: 20;
left: 20;
width: 500px;
height: 500px;
overflow: auto;
z-index: 50;
}
#front {
position: absolute;
top: 20;
left: 20;
z-index: 100;
}
</style>
</head>
<body>
<div id="back"></div>
<div id="front">
<input type="text" value="Hello">
</div>
</body>
</html>

z-indexを使うときの問題。上のHTMLコードをFirefoxで見る(再現HTMLはこちらで)とわかるけれど、テキストフィールドのカーソルが描画されない。テキストエリアでも同じ現象が発生する。これが不具合なのか仕様なのかはわからないけれど、気持ち悪いので直したい。
原因になっているのが、#backの「overflow: auto」っぽい。これを削除すると元に戻る。ただ、スクロールバーが必要なエリアの上に何か表示したいこともあるだろうから、それでは解決にならない。
結果的に#frontにも「overflow: auto」を追加した。「overflow: visible」では直らなかったので、カーソルの描画は正常になったものの、スクロールバーを表示したくないときには工夫が必要そう。
※環境はWindowsXP Firefox2.0、FedoraCore6 Firefox1.5.0.8

アキバでCDをお買い物

木曜日からは大阪の友人が、金曜からは長野の友人が東京に遊びに来ていて、なかなか充実した週末だった。そんな中、秋葉原を訪れたときに買ったCDが2枚。

UNDER THE BLUE SKY~include GRADIUS arrange~

UNDER THE BLUE SKY~include GRADIUS arrange~

Gradius IIの古川もとあき氏のCDを発見したので購入。フュージョンな仕上がりでギターを前面に出したアレンジになっている。懐かしいメロディーも聴ける良い雰囲気のCDだ。

5th story CD「Roman」(初回限定盤)

5th story CD「Roman」(初回限定盤)

店頭のプロモ映像を見てたら良い感じだったので購入。機動新撰組萌えよ剣TV 主題歌 時代の無双花みたいな感じの曲があってカッコ良い。声以外はROYAL HUNTっぽい感じもするかな。

prototype.jsでstatic変数を書く

間違ってたら指摘よろしく。原理的にはprototype.jsに限った話ではないけれど、判りやすいのでprototype.jsの例で。
JavaScriptでstaticな変数を書くときの話。とりあえずインスタンス変数を書くときの例から。

var Hatena = Class.create();
Hatena.prototype = {
cto: 'naoya',
initialize: function() {}
}
var jnaoya = new Hatena();
var jmala = new Hatena();
jnaoya.cto = 'reikon';
alert(jnaoya.cto);
alert(jmala.cto);

これを実行すると、

reikon
naoya

となる。jnaoyaインスタンスに対してのみ、ctoに’reikon’が代入されているためだ。これで問題ないことが多いのだけど、たまにstaticな変数が欲しい場合がある。上記の例だと、jmalaのctoも’reikon’にしてくれよって感じのとき。そこでこう書く。

var Hatena = Class.create();
Hatena.prototype = {
staff: {'cto':'naoya'},
initialize: function() {}
}
var jnaoya = new Hatena();
var jmala = new Hatena();
jnaoya.staff['cto'] = 'reikon';
alert(jnaoya.staff['cto']);
alert(jmala.staff['cto']);

これで、jnaoyaもjmalaもctoはめでたく’reikon’となる。じゃあ、逆にオブジェクトだけどstaticにしたくない場合はどうするのか。そのときはこう書く。

var Hatena = Class.create();
Hatena.prototype = {
staff: null,
initialize: function() {
this.staff = {'cto':'naoya'};
}
}
var jnaoya = new Hatena();
var jmala = new Hatena();
jnaoya.staff['cto'] = 'reikon';
alert(jnaoya.staff['cto']);
alert(jmala.staff['cto']);

これの結果は最初と同じく、

reikon
naoya

となる。
なんでそうなるのかって話だけど、一つ目と三つ目はプロパティ自体を置き換えているけれど、二つ目はプロパティまで参照した上で中身だけを置き換えているために、こういう挙動になるのかなと理解している。
という訳で突っ込みどころ満載な予感。

IT戦記の中の人の記事読んだ!

WEB+DB PRESS Vol.35

WEB+DB PRESS Vol.35

やっと買った。元々、IT戦記 – はじめての雑誌><で見たときから買うことは決めていたのだけど、何か忙しくて買えていなかった。
パフォーマンスの頁はid:amachangさんらしさが良い感じだった。DOM系のメソッドなんかは今までも注意していたけれど、

for (var i = 0, len = nodeList.length; i < len; i++) {
// 処理
}

みたいなことをして、ループでのDOMアクセスを減らすなんてのは盲点だった。やたらとループの多い箇所には今度やってみよう。
自分もいつかは本に出現するくらいの人にはなりたいな、とか思ったりする。

Windows Live Spacesの使い方がわからない

Webプログラマとかやっている癖に阿呆だなと思う。
「保留中のリクエストが 1 件あります。」というのがメッセに挙がっていたので、クリックしてみたところ、

保留中のリクエス
ユーザーにスペースの表示や連絡先情報の受信を許可したり、ユーザーを友人リストや Windows Live Messenger のメンバーに追加することができます。他のユーザーからのリクエストを受信したくない場合は、リクエストの送信を禁止できます。

とか書いてある。会社の友人だし、あっさり「承認」しようと思ったんだけど、「承認」のところがチェックボックスではなくて、「プライベートの情報を入力」というアンカーになっている。
クリックすると、とりあえずスペースを作っておきなさい!って感じのページに飛ばされるので、作ってみた。でも、その後はずっとプロフィール編集の画面に飛ばされるばかりで、結局最初にやりたかった「承認」ができず仕舞い。
多分、なんか忘れているだけなんだろうけれど、昔のクソゲを思い出した。これを知らないと永久に先に進めないみたいな。いやいや、自分の注意力の無さを棚に上げまくっての話ではあるけれど。

Arch EnemyのDVDが欲しい

欲しいキャンペーンではなくてよ。
http://youtube.com/watch?v=NizPNmUjeDU
CDで初めて聴いたときはそこまで感動がなかったのだけど、ライブは面白い。笑える。勿論、アンジェラ・ゴソウの声にだけど。
デスボイスって何故か受け付けない人が多い。ラップが大丈夫なら音色が違うだけと捕らえれば良いのに、どうして先入観だらけで音と付き合うのだろうか。SLIPKNOTが聴ける癖にデスボイスが無理とか言っている人は何か勘違いしている筈だ。
デスボイスのカッチョ良さでは、今のところSoilWorkが最強だけど、Arch Enemyは見た目のギャップが笑えて素晴らしい。DVD買おうかなぁ。
因みにArch Enemyはポップスバンドなんだと思う。その証拠を貼っておこう。
http://youtube.com/watch?v=mhAT-pM4aLo
恥ずかしいくらい、ポップなコード進行だ。