【问题标题】:Binary / bit manipulation of BigInteger in C#C# 中 BigInteger 的二进制/位操作
【发布时间】:2012-08-02 23:28:05
【问题描述】:

以下代码检查给定数字是否遵循特定的二进制模式。

我编写这段代码时没有考虑字节序和数字的签名方式。

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,但没有运气。

【问题讨论】:

  • 那么 BigInteger 总是有符号并且总是小端序...
  • BigInteger 已经提供了检查它是否是 2 的幂的功能。您可以使用它来将数字切割成更小的数字,然后也可以递归地检查它们。
  • @YoryeNathan:在我的情况下这是不可能的。问题上下文太复杂,无法在这里解释,但我确实知道我需要比较二进制模式。
  • “BigInteger 总是有符号的并且总是小端序”这不再是真的了。 BigInteger 现在支持符号和字节序。

标签: c# .net binary bit-manipulation biginteger


【解决方案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] &amp; 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 给出相同的表示,无论机器字节序如何。

【讨论】:

  • 感谢您指出这一点。但是,对于大于 128 的值,两种情况下的结果都是错误的。我认为这要么是因为字节序,要么更可能是检查符号位/字节。
  • @MichaelGraczyk 不,以0xA0 为例。
  • @DanielFischer:谢谢。关于您所说的“将条件减少到else if ((bytes[b] &amp; 128) == 128)else if (bytes[b] == 128)”的评论,我实际上希望过滤掉其中包含01 序列的任何字节。因此检查所有可能的10 序列,除非您有更优化的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
相关资源
最近更新 更多