質問

非陰性整数からMSB(最も重要なビット)を取得するための次のコードがあります。 Int32 具体的には:

private static readonly int[] powersOf2 = new int[]
                                        {
                                            1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
                                            32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
                                            8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912,
                                            1073741824
                                        };

public static int GetMsb(int value)
{
    for (int k = powersOf2.Length - 1; k >= 0; k--)
    {
        var bit = (value & powersOf2[k]) != 0;
        if (bit)
            return (k + 1);
    }
    return 0;
}

繰り返しますが、その値は負ではありません。

私の質問は次のとおりです。
.NETフレームワークは、このコードがすべてのプラットフォームで適切に実行されることを保証しますか?X86/Windows/Linux/Sun/64bit?

それは Int32 .NET内の表現、を含む エンディアンネス そして、ビット/バイトの順序、プラットフォームに不可知論されていますか?

前もって感謝します!
ところで、これが一種の複製の場合は、できるだけ早くコメントしてください。ありがとう!

役に立ちましたか?

解決

あなたがそれを扱う限り として int, 、はい、それはプラットフォーム不可知論です。これには、すべての算術とビットワイズが含まれます(<< , >> など)操作。オプコードは、常にあなたが期待していることをしていることを確認します。

でも!カバーの下を覗くと、それ そうかもしれない 案件;例えば BitConverter.GetBytes(int)BitConverter.ToInt32 エンディアン性を気にします。これを確認できます BitConverter.IsLittleEndian;それは通常です true 「レギュラー」.NETで、しかしそうするかもしれません false おそらくIA64、またはいくつかのアーキテクチャではXNAまたはモノで。

同じロジックが、間に(たとえば)強制する安全でないコードに適用されます byte*int*, 、または任意 組合 経由で構築されています [StructLayout].

しかし、 通常 コード、大丈夫です。

他のヒント

エンディアンネスはプラットフォームに依存していますが、ここのコードはエンディアンネスにまったく依存していません。

エンディアンは、ポインター、組合(structlayout:explicit)、またはビットコンバーターなどの低レベルのものを使用する場合にのみ機能します。

ビットシフト、整数算術、および整数タイプ間の正常なキャストは、エンディアン不可知論者です。

あなたのコードは常に機能します。

それは、INT32の表現がプラットフォームからプラットフォームに変更されないためではなく、コードがそれに依存しないほど十分に書かれているためです。フォーマットが変更された場合、変更はテストしている数と、2テーブルのパワーのエントリの両方に等しく影響します。そのため、コードは機能します。

コードはポータブルですが、MSBとして0を返します int.MinValue 署名済みの整数で作業しているため、ヘキサでは実際には0x80000000です。これは、すべてのビットで機能するコードです、と私は信じており、事前に計算された値は必要ありません。

public static int GetMsb(int value)
{
    for(int i = 31; i >= 0; i--)
    {
        if ((value & 0x80000000) != 0) return i;
        value <<= 1;
    }
    return 0;
}

またはaで uint:

public static int GetMsb(uint value)
{
    for(int i = 31; i >= 0; i--)
    {
        if ((value & 0x80000000) != 0) return i;
        value <<= 1;
    }
    return 0;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top