【问题标题】:.NET - Is the MSB of int32 platform agnostic?.NET - int32 平台的 MSB 是否不可知?
【发布时间】:2011-05-30 07:42:17
【问题描述】:

我有以下代码用于从非负整数 Int32 中获取 MSB(最高有效位),更具体地说:

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?

.NET 中的Int32 表示形式(包括字节顺序和位/字节顺序)是否与平台无关?

提前致谢!
顺便说一句,如果这是一种重复 - 请尽快对此发表评论。谢谢!

【问题讨论】:

  • base-2 数字系统没有特定的平台。

标签: .net integer platform-agnostic


【解决方案1】:

只要您将其视为int,是的,它与平台无关。这包括所有算术和按位(<<>> 等)操作。操作码始终确保它符合您的预期。

但是!如果您在封面下面偷看,那可能很重要;例如BitConverter.GetBytes(int)BitConverter.ToInt32 关心字节序。您可以通过BitConverter.IsLittleEndian 进行检查;在“常规”.NET 上通常是 true,但在 IA64 上可能是 false,在某些架构上可能是 XNA 或 Mono。

同样的逻辑适用于(例如)在byte*int* 之间进行强制转换的任何不安全代码,或通过[StructLayout] 构造的任何联合

但在常规代码中,你应该没问题。

【讨论】:

    【解决方案2】:

    字节序取决于平台,但您的代码完全不依赖于字节序。

    只有在使用指针、联合(StructLayout:Explicit) 或 BitConverter 等低级内容时,字节序才会发挥作用。

    整数类型之间的位移、整数算术和正常转换与字节序无关。

    【讨论】:

      【解决方案3】:

      您的代码将始终有效。

      这并不是因为 Int32 的表示不会因平台而异,而是因为您的代码编写得很好,以至于不依赖于它:您正在将 Int32 与其他 Int32 进行与运算。如果格式确实发生了变化,则该更改将同样影响您正在测试的数字以及您的 2 次幂表中的条目 - 因此代码仍然可以工作。

      【讨论】:

        【解决方案4】:

        代码是可移植的,但是,它返回 0 作为 int.MinValue 的 MSB,实际上是 0x80000000 的六进制数,因为您使用的是有符号整数。我相信这是一个适用于所有位的代码,并且不需要任何预先计算的值:

        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;
        }
        

        【讨论】:

        • “鉴于该值不是负数”。不过,感谢您提供建议的代码。
        猜你喜欢
        • 2012-09-01
        • 2016-05-09
        • 1970-01-01
        • 2011-05-28
        • 2016-06-04
        • 1970-01-01
        • 2011-09-26
        • 1970-01-01
        • 2020-10-08
        相关资源
        最近更新 更多