为什么 BigInteger.ToString(“x”) 会为signed.MaxValue(不包括)和 unsigned.MaxValue(包括)之间的值添加 0?

发布于 2024-11-13 06:15:18 字数 1133 浏览 4 评论 0原文

示例(奇怪行为旁边的星号):

    [Fact]
    public void BigInteger_ToString_behavior_is_odd()
    {
        writeHex(new BigInteger(short.MaxValue)); // 7fff
        writeHex(new BigInteger(short.MaxValue) + 1); // 08000 **
        writeHex(new BigInteger(ushort.MaxValue)); // 0ffff **
        writeHex(new BigInteger(ushort.MaxValue) + 1); // 10000

        writeHex(new BigInteger(int.MaxValue)); // 7fffffff
        writeHex(new BigInteger(int.MaxValue) + 1); // 080000000 **
        writeHex(new BigInteger(uint.MaxValue)); // 0ffffffff **
        writeHex(new BigInteger(uint.MaxValue) + 1); // 100000000

        writeHex(new BigInteger(long.MaxValue)); // 7fffffffffffffff
        writeHex(new BigInteger(long.MaxValue) + 1); // 08000000000000000 **
        writeHex(new BigInteger(ulong.MaxValue)); // 0ffffffffffffffff **
        writeHex(new BigInteger(ulong.MaxValue) + 1); // 10000000000000000
    }

    private static void writeHex(BigInteger value)
    {
        Console.WriteLine(value.ToString("x"));
    }
  • 这有原因吗?
  • 我该如何删除这个多余的零?我可以检查字符串开头是否有零,如果是,则将其删除吗?有什么极端情况需要考虑吗?

Examples (asterisks next to odd behavior):

    [Fact]
    public void BigInteger_ToString_behavior_is_odd()
    {
        writeHex(new BigInteger(short.MaxValue)); // 7fff
        writeHex(new BigInteger(short.MaxValue) + 1); // 08000 **
        writeHex(new BigInteger(ushort.MaxValue)); // 0ffff **
        writeHex(new BigInteger(ushort.MaxValue) + 1); // 10000

        writeHex(new BigInteger(int.MaxValue)); // 7fffffff
        writeHex(new BigInteger(int.MaxValue) + 1); // 080000000 **
        writeHex(new BigInteger(uint.MaxValue)); // 0ffffffff **
        writeHex(new BigInteger(uint.MaxValue) + 1); // 100000000

        writeHex(new BigInteger(long.MaxValue)); // 7fffffffffffffff
        writeHex(new BigInteger(long.MaxValue) + 1); // 08000000000000000 **
        writeHex(new BigInteger(ulong.MaxValue)); // 0ffffffffffffffff **
        writeHex(new BigInteger(ulong.MaxValue) + 1); // 10000000000000000
    }

    private static void writeHex(BigInteger value)
    {
        Console.WriteLine(value.ToString("x"));
    }
  • Is there a reason for this?
  • How would I remove this extra zero? Can I just check if the string has a zero at the start and, if so, remove it? Any corner cases to think about?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

第七度阳光i 2024-11-20 06:15:18

如果没有前导零,该数字可能看起来像是二进制补码中相同位数的数。添加前导零可确保不设置高位,因此它不可能被解释为负数。

如果第一个字符为零,则继续删除它,除非它是字符串中的唯一字符。

Without a leading zero, the number may appear as though it is a negative number of the same number of bits in two's complement. Putting a leading zero ensures that the high bit isn't set, so it can't possibly be interpreted as a negative number.

Go ahead and remove the first character, if it's a zero, unless it's the only character in the string.

是伱的 2024-11-20 06:15:18

从我的角度来看,不确定为什么要这样做,但正如您提到的转换为字符串然后删除前导零应该可以解决问题。

From my part not sure why this is done, but as you mentioned converting to string and then removing leading zero should do the trick.

握住你手 2024-11-20 06:15:18

IMO 正值应包含前导零,我相信这就是您在输出中看到这些值的原因。

为了避免,您可以为输出指定特定的格式

IMO positive values should include a leading zero and i believe that is why you see those in your outputs.

To avoid maybe you could specify a specific formatting for the output

以往的大感动 2024-11-20 06:15:18

看起来带有 x 格式说明符的 BigInteger 想要一次写出一个字节。

看这个例子:

writeHex(new BigInteger(15));

0f

因此,请随意删除开头的任何填充的 '0'

private static void writeHex(BigInteger value)
{
    Console.WriteLine(value.ToString("x").TrimStart('0'));
}

这有什么原因吗?

他们以这种方式实现它的一个很好的理由是它仍然是正确的,并且可能在他们用来实现 ToString 的紧密循环中表现更好(避免分支)。

从反射器来看,实现如下所示:

StringBuilder builder = new StringBuilder();
byte[] buffer = value.ToByteArray();

// ... A bunch of pre-amble for special cases here,
// though obviously not including the high byte being < 0x10.  Then:

while (index > -1)
{
    builder.Append(buffer[index--].ToString(str, info));
}

编辑

嗯,Ben 提出了一个很好的观点。您提供的其中一些示例输出了奇数个半字节,因此我猜其实现很奇怪:)

您仍然可以使用 string.TrimStart 函数来解决该问题。

It seems that BigInteger with the x format specifier wants to write out a byte at a time.

See this example:

writeHex(new BigInteger(15));

0f

As such, feel free to remove any padded '0' at the beginning:

private static void writeHex(BigInteger value)
{
    Console.WriteLine(value.ToString("x").TrimStart('0'));
}

Is there a reason for this?

A good reason for them to implement it this way is that it is still correct, and probably performs better in the tight loop they use to implement ToString (avoiding branches).

From reflector, the implementation looks like this:

StringBuilder builder = new StringBuilder();
byte[] buffer = value.ToByteArray();

// ... A bunch of pre-amble for special cases here,
// though obviously not including the high byte being < 0x10.  Then:

while (index > -1)
{
    builder.Append(buffer[index--].ToString(str, info));
}

Edit:

Well, Ben brought up a good point. Some of those examples you gave output an odd number of nibbles, so I guess the implementation is just quirky :)

You can still use the string.TrimStart function to get around that problem.

很酷又爱笑 2024-11-20 06:15:18

没有理由吗?

也许这只是一个怪癖!请记住,基类库是由开发人员(即人类)开发的!你可以预料到他们身上会出现一些奇怪的怪癖。

No reason?!

Perhaps this is simply just a quirck! Remember, the base class libraries were developed by developers, i.e. humans! You can expect the odd quirck to creep into them.

黒涩兲箜 2024-11-20 06:15:18

值得注意的是,在您的示例中,方法 ToByteArray 返回的 byte[] 还包含前导零字节。

因此,为了从字面上回答您的问题,您的示例采用前导零进行格式化,因为表示数字的字节数组包含前导零,并且该数组以十六进制形式输出。

It might be interesting to note that the byte[] returned by the method ToByteArray also contains a leading zero byte in your example cases.

So, to answer your question literally, your examples are formatted with a leading zero because the byte array representing the number contains a leading zero and it's that array that's spit out in hexadecimal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文