在不使用字符串的情况下实现 Int64.ToString
本文关键字:情况下 实现 Int64 ToString 字符串 | 更新日期: 2023-09-27 18:36:51
我遇到一种情况,我需要在不分配任何新对象的情况下将长整型数组转换为字符数组。我想模仿长时间完成的工作。ToString() 基本上没有实际创建字符串对象 - 而是将字符插入到预定义的数组中。我觉得这应该很简单,但我找不到任何示例 - C# 中的所有内容都使用 ToString 或 String.Format 之类的东西,C++中的所有内容都使用 stringstream、sprintf 或 ltoa。有什么想法吗?
编辑:为了澄清一点,这是经常调用的代码的关键部分的一部分,无法承受垃圾收集,因此我不想分配额外的字符串。输出实际上被放置在一个字节数组中 - 但是这个数据的接收者需要一个字节数组来表示这么长的字符,所以我试图通过转换为字符串格式而不分配新对象来减少垃圾收集。
感谢@SLaks的想法和@gypsoCoder指出我相关的答案。这确实可以解决问题:
private static byte[] chars = new byte[] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9' };
/// <summary>
/// Converts a long to a byte, in string format
///
/// This method essentially performs the same operation as ToString, with the output being a byte array,
/// rather than a string
/// </summary>
/// <param name="val">long integer input, with as many or fewer digits as the output buffer length</param>
/// <param name="longBuffer">output buffer</param>
private void ConvertLong(long val, byte[] longBuffer)
{
// The buffer must be large enough to hold the output
long limit = (long)Math.Pow(10, longBuffer.Length - 1);
if (val >= limit * 10)
{
throw new ArgumentException("Value will not fit in output buffer");
}
// Note: Depending on your output expectation, you may do something different to initialize the data here.
// My expectation was that the string would be at the "front" in string format, e.g. the end of the array, with '0' in any extra space
int bufferIndex = 1;
for (long longIndex = limit; longIndex > val; longIndex /= 10)
{
longBuffer[longBuffer.Length - bufferIndex] = 0;
++bufferIndex;
}
// Finally, loop through the digits of the input, converting them from a static buffer of byte values
while (val > 0)
{
longBuffer[longBuffer.Length - bufferIndex] = chars[val % 10];
val /= 10;
++bufferIndex;
}
}
我应该注意,这只接受正数,不做任何验证或其他任何东西。只是一种基本算法,用于实现在不分配任何字符串的情况下将长字符串转换为字节数组的目标。