3

Programming in the Key of C# で、著者は、日付 (年、月、日 -- 数値) を 32 ビット整数にパックする方法の例 (ソース コード付き) を示しています。この例では、作成者は次のように情報をパックします。

int iDate = (iYear << 9) | (iMonth << 5) | iDay;

これを正しく理解していれば、9 の左シフトはちょうど 512 (またはすべてのビット位置をカウントする場合は 1023) の値を与えます。しかし、プログラムを実行すると、2014 (年) のような値が保存されることに気付きました。このような小さな値でこれがどのように可能になるのでしょうか? このコードの一部を誤解していますか? コードを読んだり、見たり、いじったりしても、空気をきれいにするのに役立ちませんでした。

4

2 に答える 2

4

シフトは、その年が取り得る最大値を表していません (計算を間違えたとしても、左側に 9 をシフトする理由はありません)。シフトにより、各値に使用される範囲を定義できます。Int32以下は、値がシフトされた後に値がどのように編成されるかを示すASCIIです。

11111111111111111111111 1111 11111
-----------yyyyyyyyyyyY mmmM ddddD

日の値は最大で 31 であるため、5 ビットで十分です (32 の可能な値)。月には、12 の可能性に対応する 4 ビット (16 の可能な値) が必要です。スマート日付スキームを 2048 年以降も継続するには、年には少なくとも 12 ビットが必要です。

そのため、月の値を 5 回シフトし、年の値を 9 回シフトします。また、これが Int16 では不十分な理由です。日付を格納するには 16 よりも多くのビットが必要です。

于 2014-03-22T09:58:21.813 に答える
2

1 から始めた場合、9 だけ左にシフトすると 512 になる可能性があります。しかし、ここで起こっていることは、実際には下位 9 ビットが使用されていないのに、下位 9 ビットが数値を格納するために使用されていると仮定することですその値を保存します。左に 9 シフトすると、「使用済みビット」が 9 だけ左に移動し、下位 9 ビットが解放されます。その 9 ビットの部分には、512 の異なる値 (0 から 511) しか保存できませんが、それはあなたが何年も使用している部分ではありません。

絵として表現すると、値が「重複」しないと仮定すると、最終的にはこのようになります (突然 16 か月以上、または 32 日以上になる場合を除き、重複するべきではありません)。

syyy yyyy yyyy yyyy yyyy yyym mmmd dddd

予見可能な将来のために、何年にもわたって十分な余地があります。

于 2014-03-22T09:58:15.053 に答える