掃除をしなくては…(思うだけ)
ここのところ,忙しかったり体調を崩したりで掃除をさぼっていたため,部屋がちらかったりほこりがたまったり,冷蔵庫の中に危険物があったりと,実によろしくない住環境になりつつあります.そろそろ気合を入れて片付けなくてはなりません.
でも今日はちょっと….
今週末には頑張ります.多分….
NaN だと…
これまであまり気にすることもなく使っていた double(倍精度浮動小数点数)ですが,最近になって Inf や NaN の扱いを考える機会があり,存外にややこしくて困りました.
Inf は無限大を意味する値で +Inf と -Inf があります.+Inf == +Inf と -Inf == -Inf は true になります.ちなみに std::numeric_limits
NaN は数として評価できないことを示します.大小関係が成立しないという特徴があり,NaN < 0.0 は false となり,同時に NaN >= 0.0 も false となります.おまけに,NaN == NaN は false となり,NaN != NaN も false となります.なんだかもやもやします.
さらに細かい話をすると NaN にも種類があるようなのですが,そこまでは気にしないことにしました.
ちなみに,大小比較に依存する std::set なんかは,NaN を入れると動作は未定義になるようです.もちろん,std::unordered_set も等号が成立しないので酷いことになると思います.
Tricks for Bitwise Interleaving and Deinterleaving
概要
ビット単位の Interleave を効率化する手法を見つけたので,単純な実装と比べてみました.
- Interleave bits by Binary Magic Numbers - Bit Twiddling Hacks
Deinterleave については,Interleave の演算を概ね逆向きに適用することで実現できます.
ちなみに,ビット単位の Interleave は groonga の位置情報検索に使われています.
- groongaで高速な位置情報検索 - ククログ(2011-09-13)
比較の結果をまとめると,Interleave/Deinterleave にかかる時間を 1/10 にできました.また,groonga 付属のベンチマークによると,位置情報検索にかかる時間は 9/10 くらいになるようです.
環境
$ clang -v clang version 3.2 (tags/RELEASE_32/final) Target: x86_64-unknown-linux-gnu Thread model: posix
ビルド方法
$ clang++ -std=c++11 -Wall -O2 benchmark.cpp
実行結果
$ ./a.out Generating points: 1063000 [ns] Generating values: 4919000 [ns] Testing fast implementations: 925000 [ns] naive_interleave: 2169113000 [ns] -> average 129 [ns] fast_interleave: 195374000 [ns] -> average 11 [ns] naive_interleave: 2036491000 [ns] -> average 121 [ns] fast_interleave: 244196000 [ns] -> average 14 [ns] naive_interleave/deinterleave: 4202892000 [ns] -> average 250 [ns] fast_interleave/deinterleave: 482340000 [ns] -> average 28 [ns]
久しぶりにマクロを使って落とし穴にはまる
最近は C++ ばかり使っていたためか,久しぶりに C 言語を書いていてマクロの落とし穴にはまってしまいました.落とし穴というのは,do while トリックを使ったマクロの内部で変数を用意したところ,マクロの引数として渡される変数の名前と被って期待通りの結果にならなかったというものです.
たとえば,以下のマクロを使うとき,&value を第一引数(dest)として渡すと楽しいことになります.楽しすぎて睡眠時間が減りかねないので注意してください.
#define MACRO(dest, src) do {\ int64_t value;\ value = ...;\ memcpy(dest, &value, sizeof(value));\ } while (0)
マクロを使うのが久しぶりだったおかげで,マクロの内部では変数に対する名前の付け方を変えるべきなのを忘れていたというオチです.