.NET - MSB платформы int32 не зависит? - PullRequest
3 голосов
/ 24 декабря 2010

У меня есть следующий код для получения 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 Framework, что этот код будет правильно работать на каждой платформе: x86 / Windows / Linux / Sun / 64bit?

Является ли представление Int32 внутри .NET, включая Порядковый номер и порядок бит / байт, независимо от платформы?

Заранее спасибо!
Кстати, если это своего рода дубликат - пожалуйста, прокомментируйте это как можно скорее. Спасибо!

Ответы [ 4 ]

3 голосов
/ 24 декабря 2010

Пока вы воспринимаете это как int, да, это не зависит от платформы.Это включает все арифметические и побитовые (<<, >> и т. Д.) Операции.Опкоды всегда гарантируют, что он делает то, что вы ожидаете.

Однако!Если вы заглядываете под одеяло, это может иметь значение;например BitConverter.GetBytes(int) и BitConverter.ToInt32 заботятся о порядке байтов.Вы можете проверить это с помощью BitConverter.IsLittleEndian;обычно это true в «обычном» .NET, но может быть false, возможно, в IA64, или XNA или Mono в некоторых архитектурах.

Та же логика применяется к любому небезопасному коду, который приводит (например,) между byte* и int*, или любыми объединениями , построенными с помощью [StructLayout].

Но в обычном коде с вами все будет в порядке.

2 голосов
/ 24 декабря 2010

Порядковый номер зависит от платформы, но ваш код здесь вообще не зависит от порядкового номера.

Порядковый номер вступает в игру, только когда вы используете низкоуровневые вещи, такие как указатели, объединения (StructLayout: Explicit) или BitConverter.

Сдвиги, целочисленная арифметика и нормальное приведение между целочисленными типами не зависят от порядка байтов.

1 голос
/ 24 декабря 2010

Ваш код всегда будет работать.

Это не потому, что представление Int32 не будет меняться от платформы к платформе, а потому, что ваш код написан достаточно хорошо, чтобы не полагаться на него: вы ANDing Int32 с другими Int32. Если формат действительно изменится, это изменение повлияет как на число, которое вы тестируете, так и на записи в вашей таблице степеней 2, так что код все равно будет работать.

0 голосов
/ 24 декабря 2010

Код переносимый, однако он возвращает 0 как MSB для 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;
}

или с uint:

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