Двоичные/битовые манипуляции с BigInteger в С#

Следующий код проверяет, соответствует ли заданное число определенному двоичному шаблону.

Я написал этот код без учета порядка следования байтов и того, как число подписано.

public static bool IsDiagonalToPowerOfTwo (this System.Numerics.BigInteger number)
{
    byte [] bytes = null;
    bool moreOnesPossible = true;

    if (number == 0) // 00000000
    {
        return (true); // All bits are zero.
    }
    else
    {
        bytes = number.ToByteArray();

        if ((bytes [bytes.Length - 1] & 1) == 1)
        {
            return (false);
        }
        else
        {
            for (byte b=0; b < bytes.Length; b++)
            {
                if (moreOnesPossible)
                {
                    if (bytes [b] == 255)
                    {
                        // Continue.
                    }
                    else if
                    (
                        ((bytes [b] & 128) == 128) // 10000000
                        || ((bytes [b] & 192) == 192) // 11000000
                        || ((bytes [b] & 224) == 224) // 11100000
                        || ((bytes [b] & 240) == 240) // 11110000
                        || ((bytes [b] & 248) == 248) // 11111000
                        || ((bytes [b] & 252) == 252) // 11111100
                        || ((bytes [b] & 254) == 254) // 11111110
                    )
                    {
                        moreOnesPossible = false;
                    }
                    else
                    {
                        return (false);
                    }
                }
                else
                {
                    if (bytes [b] > 0)
                    {
                        return (false);
                    }
                }
            }
        }
    }

    return (true);
}

Как я могу настроить этот код, чтобы он соответствовал прямому порядку байтов и знаку? Я пытался подписаться на MSDN. но безуспешно.


person Raheel Khan    schedule 05.08.2012    source источник
comment
Ну, BigInteger всегда подписан и всегда имеет прямой порядок следования байтов...   -  person craig1231    schedule 06.08.2012
comment
BigInteger уже предоставляет функциональность для проверки того, является ли это степенью двойки. Вы можете использовать это, чтобы разрезать число на более мелкие числа и проверить их, возможно, рекурсивно.   -  person SimpleVar    schedule 06.08.2012
comment
@YoryeNathan: в моем случае это невозможно. Контекст проблемы слишком сложен, чтобы объяснять его здесь, но я точно знаю, что мне нужно сравнивать бинарные шаблоны.   -  person Raheel Khan    schedule 06.08.2012
comment
Что ж, BigInteger всегда подписан и всегда имеет прямой порядок байтов, это уже не так. BigInteger теперь поддерживает как знак, так и порядок следования байтов.   -  person Gavin Williams    schedule 03.03.2021


Ответы (1)


Тест

else if
        (
            ((bytes [b] & 128) == 128) // 10000000
            || ((bytes [b] & 192) == 192) // 11000000
            || ((bytes [b] & 224) == 224) // 11100000
            || ((bytes [b] & 240) == 240) // 11110000
            || ((bytes [b] & 248) == 248) // 11111000
            || ((bytes [b] & 252) == 252) // 11111100
            || ((bytes [b] & 254) == 254) // 11111110
        )

можно уменьшить до else if ((bytes[b] & 128) == 128). Любой из последующих тестов подразумевает первый, так что уже полностью определяет результат. Я думаю, что вы действительно хотите здесь

else if (bytes[b] == 128
         || bytes[b] == 192
         || bytes[b] == 224
         || bytes[b] == 240
         || bytes[b] == 248
         || bytes[b] == 252
         || bytes[b] == 254
        )

Кроме того, представление фиксировано, ToByteArray дает одно и то же представление независимо от машинного порядка следования байтов.

person Daniel Fischer    schedule 05.08.2012
comment
Спасибо что подметил это. Однако результаты в любом случае ложны для значений больше 128. Я предположил, что это произошло либо из-за порядка следования байтов, либо, что более вероятно, из-за проверки знакового бита/байта. - person Raheel Khan; 06.08.2012
comment
@MichaelGraczyk Нет, рассмотрим, например, 0xA0. - person Daniel Fischer; 06.08.2012
comment
@DanielFischer: Спасибо. Что касается вашего комментария о сокращении условия до else if ((bytes[b] & 128) == 128) или else if (bytes[b] == 128), я на самом деле хочу отфильтровать любой байт, в котором есть последовательность 01. Таким образом, проверяя все возможные последовательности 10, если у вас нет более оптимизированного предложения. - person Raheel Khan; 07.08.2012