対数あれこれ
苦手な対数のお勉強だ。
x = n p
のとき、p は n を底とする x の対数と呼び、以下のように表記する。
p = log n x
プログラミング言語では、定数 e を底とする自然対数を返す log (number)
関数が定義されていることが多い。任意の数 n を底とした対数が得たければ、以下のようにする。
log n x = log (x) / log (n)
ここで突然、ソケットの話になる。Winsock で、ネットワークイベントを Win32 イベントオブジェクトで受け取る手法がある。
// ソケットを作る SOCKET s = socket (AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET != s) { // イベントを作る(CreateEvent ()でもよい) HANDLE hEvent = WSACreateEvent (); if (WSA_INVALID_EVENT != hEvent) { // connect をイベントで待機する int nRet = WSAEventSelect (s, hEvent, FD_CONNECT); if (SOCKET_ERROR != nRet) { // 接続 struct sockaddr_in RemoteAddr; ZeroMemory (&RemoteAddr, sizeof RemoteAddr); RemoteAddr.sin_family = AF_INET; RemoteAddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); RemoteAddr.sin_port = htons (60000); nRet = connect (s, (sockaddr*) &RemoteAddr, sizeof RemoteAddr); // イベント待ち DWORD dwWaitResult = WaitForSingleObject (hEvent, 60000); if (WAIT_OBJECT_0 == dwWaitResult) { WSANETWORKEVENTS NetworkEvents; ZeroMemory (&NetworkEvents, sizeof NetworkEvents); // イベント内容を調べると同時にイベントをリセットする nRet = WSAEnumNetworkEvents (s, hEvent, &NetworkEvents); if (SOCKET_ERROR != nRet) { // イベント内容はビットフラグ if (FD_CONNECT & NetworkEvents.lNetworkEvents) { if (NetworkEvents.iErrorCode [FD_CONNECT_BIT]) {// エラーは配列のビット位置 // エラー処理(接続失敗) } else { return true; // コネクト完了なら戻すとか } } } } } WSACloseEvent (hEvent); } closesocket (s); }
まあ、connectならこんな手続きだけど、この、NetworkEvents.lNetworkEvents
の特定のビットが立っていたら、そのエラーを調べるのが、「ビットフラグのビット位置」なのが、大変やりにくいとかねがね思っていた。だって、FD_CONNECT
とか、FD_CONNECT_BIT
の定義がこうなってるんだもん。
#define FD_CONNECT_BIT 4 #define FD_CONNECT (1 << FD_CONNECT_BIT)
つまり、
FD_CONNECT == 2 FD_CONNECT_BIT
ってことじゃん?じゃあこんな関数が定義できるかと思って。
inline int GetNetworkErrorCode (LPWSANETWORKEVENTS lpNetworkEvents, long lNetworkEvent)
{
// lpNetworkEvents に格納されている、lNetworkEvent に対応するエラーコードを得る
return lpNetworkEvents->iErrorCode [log (lNetworkEvent) / log (2)];
}
ほんとかな。C言語のlog関数も自然対数なんかどうかは知りません。
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/1266
コメント