【发布时间】:2010-09-18 06:44:53
【问题描述】:
数字大于int & long,但可以容纳在Decimal。但是普通的ToString 或Convert 方法不适用于Decimal。
【问题讨论】:
标签: c# decimal hex type-conversion
数字大于int & long,但可以容纳在Decimal。但是普通的ToString 或Convert 方法不适用于Decimal。
【问题讨论】:
标签: c# decimal hex type-conversion
【讨论】:
我必须同意 James 的看法 - 手动执行 - 但不要使用 base-16。使用基数 2^32,一次打印 8 个十六进制数字。
【讨论】:
我想一种选择是继续从它上取下块,然后转换单个块?一些 mod/division 等,转换单个片段...
那么:你期望的十六进制值是多少?
这里有两种方法...一种使用十进制的二进制结构;一个手动完成。实际上,您可能想要进行测试:如果 bits[3] 为零,请快速进行,否则手动进行。
decimal d = 588063595292424954445828M;
int[] bits = decimal.GetBits(d);
if (bits[3] != 0) throw new InvalidOperationException("Only +ve integers supported!");
string s = Convert.ToString(bits[2], 16).PadLeft(8,'0') // high
+ Convert.ToString(bits[1], 16).PadLeft(8, '0') // middle
+ Convert.ToString(bits[0], 16).PadLeft(8, '0'); // low
Console.WriteLine(s);
/* or Jon's much tidier: string.Format("{0:x8}{1:x8}{2:x8}",
(uint)bits[2], (uint)bits[1], (uint)bits[0]); */
const decimal chunk = (decimal)(1 << 16);
StringBuilder sb = new StringBuilder();
while (d > 0)
{
int fragment = (int) (d % chunk);
sb.Insert(0, Convert.ToString(fragment, 16).PadLeft(4, '0'));
d -= fragment;
d /= chunk;
}
Console.WriteLine(sb);
【讨论】:
decimal Normalize(this decimal v) { return v/1.0000000000000000000000000000m; } 可以很好地工作
我相信这会在返回任何内容时产生正确的结果,但可能会拒绝有效的整数。我敢说这可以通过一些努力来解决......(哦,目前它也会因负数而失败。)
static string ConvertToHex(decimal d)
{
int[] bits = decimal.GetBits(d);
if (bits[3] != 0) // Sign and exponent
{
throw new ArgumentException();
}
return string.Format("{0:x8}{1:x8}{2:x8}",
(uint)bits[2], (uint)bits[1], (uint)bits[0]);
}
【讨论】: