四捨五入でも int の使用は避けるべきでは。。。?2006年11月27日 16時23分33秒

相も変わらず Perl のお話。

「perl 四捨五入」でぐぐると、大抵のサイトで以下の方法が紹介されているわけなんだけれども、

$int_value = int($float_value + 0.5);

その一方で、ラクダ本にはこの int 関数の脆弱性が示されている。以下のコードを実行すると、

$\ = "\n";
print 6.725 / 0.025;
print int(6.725 / 0.025);

86 系のプロセッサであれば、OS に関係なく、恐らく以下のように出力されるんではないかと思う。

269
268

野暮ったい説明は好きじゃないので、何でか知りたい人は以下のコードを試して欲しい。あるいは素直にラクダ本買ってくれ。

$\ = "\n";
print 6.725 / 0.025;
print sprintf '%.20f', 6.725 / 0.025;   # この値の正体を、とくとご覧あれ
print int(6.725 / 0.025);

で、おんなじようなことは四捨五入でも起こりうるんじゃないかと思って試してみたらやっぱり起こったわけですよ。以下、実証コード。

$\ = "\n";
print 6.725 / 0.05;
print int(6.725 / 0.05 + 0.5);

結果は以下の通り。

134.5
134

で、当のラクダ本では何て書いてあるのかというと、こんな風に書いてある (近藤氏による訳をそのまま引用)。

たいていの場合、sprintfprintf、または POSIX::floorPOSIX::ceil 関数を使ったほうが、int よりも良い結果をもたらすだろう。

POSIX モジュールはありがたいことに Win32 版の ActivePerl にも付属していて、ちゃんと動作する。そこで、Windows XP 環境にて、以下のサンプルを用いて実際の動作を試してみることにする。

use POSIX qw(floor);
$\ = "\n";
$var = 6.725 / 0.025;
print $var;
print int $var;
print floor($var);
print sprintf '%d', $var;
print sprintf '%d', "$var";

結果は以下の通り。

269
268
268
268
269

sprintf 関数に、変数 $var文字列コンテキストで渡した場合のみ、期待通りに動いてくれた。もちろん四捨五入のケースでも同様。

use POSIX qw(floor);
$\ = "\n";
$var = 6.725 / 0.05 + 0.5;
print $var;
print int $var;
print floor($var);
print sprintf '%d', $var;
print sprintf '%d', "$var";
135
134
134
134
135

この辺、十分に検証せずにコードを書いてしまうと、信頼性の低いシステムを組んでしまうことにもなりかねないので、注意が必要なんではないかと思う。

つか、そもそもこういう計算で正確な概数を求めたいケースってのは事務仕事に限られてくるわけで、最初から内部表現は整数だけにして誤差が起こりえないような設計にしろよって話になりそうな気もするが。例えば 0.025 で割る替わりに、40 で掛けてみるとか。。。


Thu Nov 30 23:48:42 JST 2006 - 追記

1.15。。。そんなあっさり再現するとは。。。\(^O^)/

ちなみに、上で書いたように文字列コンテキストで渡しても無駄っぽいです。当たり前か、数値コンテキストに変換されるわけだから。

$n = 1.15;
printf("%.1f\n", $n);
printf("%.1f\n", "$n");
1.1
1.1

Math::Round はその辺うまいこと解決してくれるのかなぁ。。。やってみたいけど、でも今標準モジュールじゃないものを入れてしまいたくはないしなぁ。。。 (個人的事情により)

狐に摘まれたような話2006年11月27日 20時36分41秒

この分野に関しては、アメリカのRiyaが先ごろ、注目の新技術を発表した。Like.comというそのサービスは、静止画像をダイレクトに検索できる。検索キーはテキストのワードではなく、別の画像だ。たとえばハリウッド女優が写っているイメージの中で、女優がつけている時計を画像として切り出し、その画像と似た画像をデータベースの中から抽出できる(→関連記事)

(中略)

 こうした技術が実用化されていけば、ビジネスの可能性は限りなく大きい。なぜならGoogleが道を切りひらいたコンテンツマッチ広告は、今後間違いなく動画や音声の世界へと進出していくからだ。テレビCMという広告モデルが崩壊しつつあることはすでに多くの人が指摘しており、アメリカではすでにテレビCM市場そのものが縮小局面に入ってきている。日本ではまだそこまでの段階には至っていないが、しかし民放各局の2006年9月中間期決算は、各社ともスポット広告が前年同期比で減少した。11月20日の日経産業新聞にはこうある。

気が早すぎない? おいらは Like.com が仮に完成したとして、それがとても便利なサービスであるとはとても思えないよ。少なくとも UA がドキュメントの要素に対する考え方を改善し、画像の一部分のみを「画像として切り出」す (よーするに、ブラウザの中で画像をトリミングしてコピペする) ことができるようにでもならない限り (そして、それを貼り付けるフォームや、その内容を転送するファイル形式やプロトコルを定義して W3C にでも勧告してもらって主要ブラウザに実装してもらわない限り)、誰も使う気になんてなれないと思うよ。

夢を語るのは構わないけど、それを実現する為に整えるべき足元についても議論する必要はあるんじゃない? 映像 (静止画・動画を問わず) や音声は今、テキストほど簡便には扱えないという現実は、重く受け止めなきゃならない。検索エンジンだけでそれを実現したところで、限定的な用途にしか使えないだろう。

そこでタギングではなく、もっとダイレクトに動画データを検索できるシステムはないものか――という話になる。そしてこれは、上記に書いたような放送業界の事情だけでない。ソーシャルタギングでは処理しきれない、いままさにストリーミングされているようなリアルタイムで放送中の動画に関しては、やはり動画検索の方が使い勝手が良いというポイントも忘れてはならない。ネットの世界でも、たとえばGoogleはGoogle Image Labelerで、Googleのデータベースに収められている膨大な量の静止画像に対し、ユーザー参加型の対戦ゲームによって自動的にタグを付与していくという試みを行っている。

このセンテンスの意味がよーワカランのよね。動画を「どう」検索するつもりなの? そしてそれができることによって、どんな利便性を得ることができるの? 今何が放送されているのかを知りたければ新聞のテレビ欄かインターネット TV ガイドでも見ればいいし、それって結局テキストの検索でしかないし。

例えばあるテレビ番組中に、特定のタレントが出演しているシーンを検索するとか、そういうことなのかなぁ。だとすると、そのタレントの外見的情報を様々な角度 (意味的な角度ではなくて本当に角度^-^;) で保存した膨大な DB を用意して、それらを用いた大掛かりなイメージパターンマッチングを行う、っていうそんな仕掛けになるのかしら。面白いかもしれないけど、解析にかかる時間や膨大な DB を格納するインフラを心配する以前に、それらのデータを用意するのは人間の作業である、っていう点を考慮すると。。。イマドキの大作ゲームが制作費で悲鳴を上げている現状になんとなーくシンクロしてしまうようなそんな悪寒が ((((((((((((((((/;^^)/ 。

あ、だからそのデータ集めをソーシャルに任せるって話か。無理無理、そこまで頑張って利便を手に入れようなんて人は果てしなく少ないし、ブログとかに写真が貼り付けられることを期待してクロールしたところで、著作権やら肖像権やらの問題とかもあって (特に日本人は善良な人が多いからエロサイト系以外は気にかけている人がほとんどなのよね)、大して情報は集まらないって。。。あ、しょこたんみたいにタレントが自身で写真だらけのブログを作ってくれればいいのかw