土日は風邪を引いて非常に調子が悪かったです。せっかくの土日なのに何も出来なかった、もったいない…。今日は熱はなんとかなりましたが、腹が痛い。
腹に来る風邪はあまり引いたことがないので、非常に参っております。同期に「目が死んでるぞ、大丈夫か?」って言われました。会社に来るくらいは大丈夫だったつもりなんですが、僕の気持ちは周りには伝わっていなかったようです。
ああ、さっさと帰りたいような、腹が痛いから動かずじっとしていたいような…。
高校、中学のときには語呂合わせとか、替え歌に乗せて覚えたなあ。世界史の時間にアルプス一万尺の替え歌で、中国歴代国家なんてのを教えてもらったっけ。懐かしいなあ…。
踏切に人が倒れていたとかで、50分くらい電車が止まっていました。今日に限らずJR西日本は頻繁に遅れます。5〜6月には2週間に1回くらい遅れてました。
Wikipedia曰く、JR西日本の路線は私鉄が併走している区間が多いので、より良いサービスを展開しようとしてかなり無理しているようです。確かに私鉄より速いし、列車も綺麗だし、一本で行ける距離が長いです。
じゃあ東と西はどのくらいロングランに差があるんでしょうか?ってことで、まずはJR東日本の路線長(出典Wikipedia)です。都心を突っ切るタイプを挙げておきます。
以上が都内を突っ切る長い路線です。中でも京浜東北線(直通根岸線)が長いかな?両者を足すと80キロくらいです。大船って遠いんだなあ…。
対するJR西日本はかなり長い距離を走ってきます。普通列車の西明石 <-> 京都ですとほぼ100キロですね。
しかしJR西日本にはもう一つ、新快速という編成があります。調べてみると、姫路 <-> 敦賀といった特急顔負けのロングランです。以下、始発から終点までのキロ数を計算してみました。
最優先のくせに長距離だから、遅れると他の列車に多大な影響を及ぼすんですね。こんなのが1時間に4本も走ってるんだから、時間通りに来る方が奇跡なのかもしれない。今後10分くらいは遅れても温かい目で見守ろうと思います。
高校の数学で習った「必要条件、十分条件」って覚えてますか?
x = 0はxy = 0の何条件か?
という奴です。いきなり言われても、ん、どっちがどれだっけ?ってなりますね。
ネットに丁寧な解説がたくさんありますが、自分はこのサイトでわりとすんなり理解できました。「十分から必要に流れる」という覚え方は良いね。
そして必要十分条件を誤解していた事もわかりました。語感からか厳しさの順が「必要十分>十分>必要」と感じるのでしょう、世の中では必要十分が間違って使われまくりですね。人のことは言えませんけどね。
上記サイトのベン図を見れば厳しさの順(つまり条件の狭さ)が「十分>必要十分>必要」ってことが分かると思います。既におわかりのことと思いますが、冒頭の問題は「十分条件」です。
今更ですがscreenを使い始めました。Windowsのタスクバーが仮想ターミナル5〜6個で埋まる(グループ化は嫌い)のも、それはそれで一興なんですけど。screenは研究室に居たときに hdk氏が絶賛していたというか、氏の一部となっていましたね。
早速使ってみると、特殊なことをしなくてもスクロールして履歴を検索して、コピーペーストできたりしてナイスです。Ctrl+Aが押しづらくて、bashと被ってるのがイライラします。早いところ変えなきゃ…と思いつつ変えてません。今はプログラム書いたりしていないので、それほど必要ないのです。
しかも使ってるサーバが毎日シャットダウンされるので、attach/detachというscreenの本領が発揮できません。使い始める時期も場所も間違えた気がする…。いつか引っ越して自宅鯖を復活させるまでは、練習しとくか。
会社でネットを見ているときに変なリンクをクリックすると、プロキシが検知して、業務に関係ないページは見んな、みたいなメッセージが出ます。ご丁寧にもシステムが「こいつ仕事してませんよ!」って上司にチクってくれるそうです。全自動でね。
どうせ仕事しない奴は何言ったって仕事しないんだから、ネット封鎖なんて意味がないような…。ま、それはさておき、プロキシの運用ポリシーは普通で、HTTP, FTP, HTTPSが通ります。大抵は正常に動いてますが、突然白紙のページを返したりしてくるお茶目さんなときもあります。過負荷かしら?
プロキシからのHTTPレスポンスを見て、どこの製品か見当付けたは良いものの、去年辺りに他社に売却されたらしくて情報がありません。そんな素敵なシステムを一体いくらで売りつけられ売ってくださっているのか知りたかったんですけど…残念ねえ。
奈良に行って唐招提寺の金堂(修理中)を見てきました。触れるくらい目の前に屋根瓦があるのはなんとも不思議な気分です。
行きは迷いました。名神高速 -> 近畿道 -> 第二阪奈道という道順のはずが、なぜか神戸の三宮に居ました。関西の高速道路は意味が分からん。
帰りも迷いました。R24 -> R163 -> R170のはずが、突然コースアウトしていて県道16号に入っていました。関西の下道は意味が分からん…。
関東では旅行先でもなければこんなに迷わなかったが、関西だと近所でなぜこんなに迷うのか。地図もあったし、4人も居たのに…。
帰り道、迷う理由を考えていたら、R170からコースアウトしたわけですが、そこで一つ気がつきました。青看板が出現するタイミングが非常に遅いのです。
大抵の道では、分岐する地点の真上に看板があり、看板が見えたらもう手遅れです。本来行くはずだった道を悲しく見送るだけしかできません。
そして本日走ったR170はさらに上の作りでして、陸橋に完全に乗った後に「陸橋の下に」看板が出ます(※)。
「正解は『陸橋の手前で左に降りて、右折。』でした。残念っ…!」ってか。
道案内はクイズじゃねーぞ、いい加減にしろこの野郎が。
まあ、半分冗談で半分本気です。
(※)実は手前にも青看板はあるんですが「陸橋から左に抜けて、その後右折」なんて情報は読み取れません。無理言うな。
何度インストールしてもまたインストールしろと言われるKB928366(Microsoft .NET Framework, Version 1.1 Service Pack 1用セキュリティ更新プログラム)ですが、やっと黙らせることができました。
まずは Windows Installer Clean Up というツールをインストールして、起動します。
こんな画面が出ますので、.NET 1.1と名の付く項目を全部removeします。そのあと、.NET 1.1と .NET 1.1 SP1をインストールしてから、Microsoft UpdateでKB928366をインストールすると成功しました。
にしてもMicrosoft Updateはトラブルが多い。何でもかんでも一カ所でアップデートできるようにしたせいでしょうか。人ごとながらMSも検証大変そうだなあと思う…。
今日はコードを2つ紹介(出典: ハッカーのたのしみ, Henry S. Warren, Jr., 滝沢ら訳)しますがどれもメチャクチャわかりづらいです。どちらも可読性なんかかなぐり捨ててとにかく効率を追った、ある意味潔いコードです。GNU netcatも中途半端に読みづらい変なコードを書くくらいなら、このくらいやって欲しかったなあ。
本についてですけど、前半はまだわかる気がしますが、後半はあまりにも頑張りすぎていて全然わからんです…。こういうコードを読んでいると、根性っていうか、ハッカー達の職人魂みたいなものを感じますよ。
さて1になっているビットを数える処理ですが、比較的わかりやすいコードを一つ例にとってみようと思います。
unsigned int x;
int count;
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);
count = x;
以上は32ビット用のコードです。ぱっと見だと、なんじゃこりゃ?って感じですね。このコードでは隣り合う桁を足していきます。最初は隣の1桁、次は2桁、次は4桁という風に倍々ゲームにしていきます。
では8ビットで検証してみます。
x = [ 1][ 0][ 1][ 1][ 0][ 1][ 0][ 0] 1ビット毎の : 1, 0, 1, 1, 0, 1, 0, 0 1の個数 : x = [ 1][ 0][ 1][ 1][ 0][ 1][ 0][ 0] x>>1 = [ 1][ 0][ 1][ 1][ 0][ 1][ 0][ 0] 0x55 = [ 0][ 1][ 0][ 1][ 0][ 1][ 0][ 1] x&0x55 = [ 0][ 0][ 0][ 1][ 0][ 1][ 0][ 0] (x>>1)&0x55 = [ 1][ 0][ 1][ 0][ 0][ 0][ 0][ 0] x = [ 0 1][ 1 0][ 0 1][ 0 0] 2ビット毎の : 1 + 0 = 1, 1 + 1 = 2, 0 + 1 = 1, 0 + 0 = 0 1の個数 : x = [ 0 1][ 1 0][ 0 1][ 0 0] x>>2 = [ 0 1][ 1 0][ 0 1][ 0 0] 0x33 = [ 0][ 0][ 1][ 1][ 0][ 0][ 1][ 1] x&0x33 = [ 0 0][ 1 0][ 0 0][ 0 0] (x>>2)&0x33 = [ 0 1][ 0 0][ 0 1][ 0 0] x = [ 0 0 1 1][ 0 0 0 1] 4ビット毎の : 1 + 2 = 3, 1 + 0 = 1 1の個数 : x = [ 0 0 1 1][ 0 0 0 1] x>>4 = [ 0 0 1 1][ 0 0 0 1] 0x0f = [ 0][ 0][ 0][ 0][ 1][ 1][ 1][ 1] x&0x0f = [ 0 0 0 0][ 0 0 0 1] (x>>4)&0x0f = [ 0 0 1 1][ 0 0 0 1] x = [ 0 0 0 0 0 1 0 0] 8ビット毎の : 3 + 1 = 4 1の個数 : よってxには1が4つ含まれていた。
このように検証してみますと、1の数を倍々でまとめていって最後にはxの右端にビットの個数が集約されて計算されることが分かります。凄いんですけど、なんともトリッキーですねえ。
もう一つ似たようなコードで、パリティを求める処理が書けます。単純にパリティを求めるならば、全てのビットのxorを取れば良いのですが、この本では以下のように書きます。
unsigned int x, y;
int parity;
y = x ^ (x >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
y = y ^ (y >> 8);
y = y ^ (y >> 16);
parity = y & 1;
以上は32ビット用のコードです。やはりこれもぱっと見では、なんじゃこりゃ?って感じです。これも2進数の1桁分, 2桁分, 4桁分…とxorを取っていって最後に32桁分のxorがyの右端に来るという仕掛けです。
では8ビットでの計算の結果をご覧下さい。
x = [ 7][ 6][ 5][ 4][ 3][ 2]( 1)( 0) `-----| xor x>>1 = [ 7][ 6][ 5][ 4][ 3][ 2]( 1)[ 0] y = [ 7][ 7,6][ 6,5][ 5,4][ 4,3]( 3,2)[ 2,1]( 1,0) `-----------| xor y>>2 = [ 7][ 7,6][ 6,5][ 5,4][ 4,3]( 3,2)[ 2,1][ 1,0] y = [ 7][ 7,6][ 7-5]( 7-4)[ 6-3][ 5-2][ 4-1]( 3-0) `-----------------------| xor y>>4 = [ 7][ 7,6][ 7-5]( 7-4)[ 6-3][ 5-2][ 4-1][ 3-0] y = [ 7][ 7,6][ 7-5][ 7-4][ 7-3][ 7-2][ 7-1]( 7-0) ~~~~~~
このように検証してみますと、うまく各桁が一回ずつxorされるようにずらしながら計算していることがわかります。最後に yの右端に全てのビットのxorが計算されているのが見事ですね。
現在はコンピュータが十分高速化していて、ソフトウェアの規模も大きくなっているため、速度より保守性を重視します。要は遅くて良いから誰もが読める普通のコードが求められます。どんなに速くても誰も理解できないトリッキーなコードは歓迎されません。
ただしそれは商業サーバー用のプログラムとかPC用のプログラムでの話。もっと特殊な分野、例えば究極の速度を求める超高性能計算(計算用のライブラリとか)や、ハードがショボショボな組み込み機器などは、無駄に使えるCPUやメモリがありません。というわけで、まだまだトリッキーなコードも出番があるんじゃないかなあ?
GNU netcat 0.7.1(※)でポートのlistenはできるのに、別のホストにconnectしようすると無視されてしまいます。PCでコンパイルすると動くので、環境依存かなあ?と思ってprintfデバッグしていたら、複雑といえば複雑だけどしょうもない問題だったことに気づいてがっくり…。
以下はflagset.cの135行目あたりにあるint netcat_flag_count(void) という関数内の処理です。
char c;
int ret = 0;
while (c) {
ret -= (c >> 7);
c <<= 1;
}
この処理はcの中の1になっているビットを数える処理です。retには1だったビットの数が格納されます。例えばc = 3だったらret = 2です。
ぱっと見ret -= とマイナスするの部分が奇妙に見えます。理由としてはcの最上位ビットが1(つまりマイナスの値)ならば、c >> 7としたときに符号が維持されたままシフトされ、-1になるためです。もし最上位ビットが1でなければc >> 7は0になります。つまりc >> 7は -1 or 0になるので、ret -= で符号を反転させて足してあげています。
極めてわかりづらいです。なんでこんなことするんでしょうか。
それはさておき、このコードの何が問題かというと、char = signed charだと決めつけていることです。世の中にはchar = unsigned charとするコンパイラもあります。というか実際、そういうコンパイラが目の前にあります。しかし大抵の人がchar = signed charだと思っていることを踏まえると、char = unsigned charという設計は避けるべきだと思います。
このコンパイラを作った人は意地悪というか…ちょっとひねくれてたんでしょうね。
C言語ではcharがsigned charであるという決まりも、そもそも8ビットであるという決まりすらないので、こういうコードを書くと変な環境に持って行ったときにはまります。え、変な環境を作る方が悪い?ま、それも一理あります。
ちなみにunsiged charのときは、c >> 7の計算で符号拡張されませんので、c >> 7が -1 or 0になって欲しいはずが1 or 0になってしまい、retが減算されてしまいます。すると正負が逆になってしまって、結果netcatは引数がねーよ、と判断してしまうわけです。こんなことになるくらいならいっそsigned charなんて使わずにunsigned charを使った処理の方が感覚的にわかりやすいと思うのは私だけでしょうか?
GNUの中の人も変わってるわねえ。
まとめるとGNU netcatはchar = signed charと仮定した処理が入っていたので、char = unsigned charの環境に持って行くとおかしくなりますよ、って話でした。
それにしてもコンパイラ作者、GNUの中の人と、世の中にはひねくれ者が多いですなあ…。プログラムに限らず何事をやるにしても変な思いこみをしないように気をつけたいものです。
(※)FreeBSDやDebian GNU/Linuxは違うnetcatを使っているようです。GNU netcatを採用しているディストリビューションは少ないと思われます。
朝出かけるときに靴を履こうとしたら、バシっと乾いた音がして靴べらがへし折れました。なぜ忙いでいるときに折れるのか…。
元々短かったんじゃないか?ってくらいに真っ二つに割れていますね。まあ、百均の安物だったんだけどさ、さすがに半年も持たないというのは短すぎやしないかなあ。
何気なくGoogle Mapsで「鳥取県」と検索したら、以下のような結果が出てきました。Googleからすると、鳥取の高速バスってのはそんな一押しなのか?
他の県を片っ端から入力してみたのですが、検索結果が出てきたのは「青森県」だけで、他には一つも出てきません。「青森県」に何を求めたのか知りませんが、やたらたくさん登録されています。
ちなみに青森の検索結果は以下のようになっておりました。全国広しと言えども「青森県」の充実っぷりには敵いませんよ!
Google Mapsの「お店やサービスを検索」で頻繁に指定された単語が出ているのでしょう。しかし「鳥取」と「高速バス」がそんな頻繁に指定されているかと考えると、かなり微妙だと思います。
恐らくこの機能の利用者が少なくてうまく抽出できていないか、この機能が正常に動作してないか…だと思うんですが。とにかく変ですよね。
< | 2007 | > | ||||
<< | < | 11 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | - |
合計:
本日: