C# 为什么BigInteger.ToString(";x";)在signed.MaxValue(独占)和unsigned.MaxValue(包含)之间的值前加0?
示例(奇数行为旁边的星号):C# 为什么BigInteger.ToString(";x";)在signed.MaxValue(独占)和unsigned.MaxValue(包含)之间的值前加0?,c#,biginteger,C#,Biginteger,示例(奇数行为旁边的星号): 这有什么原因吗 我如何删除这个额外的零?我是否可以检查字符串的开头是否为零,如果是,请将其删除?有什么特殊情况需要考虑吗 我不知道为什么要这样做,但正如您提到的,转换为字符串,然后删除前导零应该可以做到这一点。使用x格式说明符的biginger似乎希望一次写出一个字节 请参见此示例: writeHex(new BigInteger(15)); 0f 因此,请在开始时随意删除任何填充的'0': private static void writeHex(BigInt
- 这有什么原因吗
- 我如何删除这个额外的零?我是否可以检查字符串的开头是否为零,如果是,请将其删除?有什么特殊情况需要考虑吗
x
格式说明符的biginger
似乎希望一次写出一个字节
请参见此示例:
writeHex(new BigInteger(15));
0f
因此,请在开始时随意删除任何填充的'0'
:
private static void writeHex(BigInteger value)
{
Console.WriteLine(value.ToString("x").TrimStart('0'));
}
这有什么原因吗
他们以这种方式实现它的一个很好的理由是,它仍然是正确的,并且在他们用来实现ToString
(避免分支)的紧密循环中可能表现得更好
从reflector看,实现如下所示:
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));
}
StringBuilder=新建StringBuilder();
字节[]缓冲区=值。ToByteArray();
// ... 这里有很多特殊情况的预习,
//虽然显然不包括高位字节<0x10。然后:
而(索引>-1)
{
Append(buffer[index-->.ToString(str,info));
}
编辑:
本提出了一个很好的观点。您给出的一些示例的输出是奇数个半字节,因此我猜实现很奇怪:)
您仍然可以使用
string.TrimStart
函数来解决该问题。如果没有前导零,则数字可能会显示为两个补码中相同位数的负数。设置前导零可确保高位未设置,因此不可能将其解释为负数
如果第一个字符是零,请继续删除它,除非它是字符串中的唯一字符。没有原因?
也许这只是一个怪癖!请记住,基类库是由开发人员开发的,即人类!你可以预料到这种奇怪的现象会潜入其中。IMO的正值应该包含一个前导零,我相信这就是你在输出中看到这些值的原因
为了避免这种情况,您可以为输出指定特定的格式,请注意,在示例中,由方法
ToByteArray
返回的byte[]
也包含一个前导零字节
因此,从字面上回答您的问题,您的示例的格式为前导零,因为表示数字的字节数组包含前导零,而正是该数组以十六进制形式显示。这很奇怪,因为它似乎是一个经过深思熟虑的设计选择,但据我所知,还没有记录在案。(但不是说你不对)所以要特别明确:当数字为正数且最有效的十六进制数字介于
8
和F
(包括)之间时,它们必须在一个0
之前加上前缀。以一种完全相似的方式,他们有时不得不在负数的十六进制数前加上一个F
,以确保它们看起来不是正数。如果value
为零,那不会打印一个空行吗?不是这样,它实际上是在写奇数个十六进制数字(4位半字节)。@Ben:哦,你说得对。我错过了其他的案子。我想那只是奇怪;)如果这就是原因,那么输出中总是会有偶数个十六进制数字。@finnw:我想你误解了。在十六进制输出中产生前导零的情况下,字节数组也包含前导零。例如,(新的BigInteger(ushort.MaxValue)).ToByteArray()
生成数组{0xFF,0xFF,0}
。这样的数组将用5个十六进制数字打印,因为最终用于十六进制格式说明符的私有方法FormatBigIntegerToHexString
,向后循环数组并打印每个元素。它对遇到的第一个字节有一个特例,允许使用1或2位数字。
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));
}