3

Int32より具体的には、負でない整数から MSB (Most Significant Bit) を取得するための次のコードがあります。

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 内の表現はプラットフォームに依存していませんか?

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

4

4 に答える 4

4

として扱う限り、プラットフォームintに依存しません。これには、すべての算術演算とビットごとの (<<など>>) 演算が含まれます。オペコードは常に、期待どおりに動作することを確認します。

でも!カバーの下をのぞくと、問題になる可能性があります。たとえば、エンディアンBitConverter.GetBytes(int)BitConverter.ToInt32気にします。BitConverter.IsLittleEndianこれは;で確認できます。通常trueは「通常の」.NET 上にありますが、falseおそらく IA64、XNA、または一部のアーキテクチャの Mono 上にある可能性があります。

byte*同じ論理が、との間int*、またはを介し​​て構築された共用体の間で (たとえば) 強制する安全でないコードに適用されます[StructLayout]

しかし、通常のコードでは問題ないはずです。

于 2010-12-24T08:23:43.093 に答える
2

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

エンディアンは、ポインター、ユニオン (StructLayout:Explicit)、BitConverter などの低レベルのものを使用する場合にのみ有効になります。

整数型間のビットシフト、整数演算、および通常のキャストは、エンディアンに依存しません。

于 2010-12-24T09:31:21.580 に答える
1

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

これは、Int32 の表現がプラットフォームごとに変わらないためではなく、コードがそれに依存しないように十分に記述されているためです。Int32 と他の Int32 の AND 演算を行っているためです。形式が変更された場合、その変更は、テストしている数値と 2 のべき乗テーブルのエントリの両方に等しく影響するため、コードは引き続き機能します。

于 2010-12-24T08:24:18.320 に答える
0

コードは移植可能ですが、符号付き整数を使用しているため、MSBint.MinValueは実際には 16 進数で 0x80000000 であるため、0 を返します。これは、すべてのビットで機能し、事前に計算された値を必要としないコードです。

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

またはuint:

public static int GetMsb(uint value)
{
    for(int i = 31; i >= 0; i--)
    {
        if ((value & 0x80000000) != 0) return i;
        value <<= 1;
    }
    return 0;
}
于 2010-12-24T10:28:36.297 に答える