0

I have a situation where I need to convert a long to a character array without allocating any new objects. I want to mimic what is done in long.ToString() without actually creating a string object, basically - instead the characters will be inserted into a predefined array. I feel like this should be pretty straightforward, but I can't find any examples - everything in C# uses something like ToString or String.Format, everything in C++ uses either stringstream, sprintf, or ltoa. Any ideas?

edit: For a little clarify, this is part of a critical section of frequently called code that cannot withstand garbage collection, hence I don't want to allocate additional strings. The output is actually placed into a byte array - but the receiver of this data expects a byte array of the character representation of this long, so I'm attempting to reduce garbage collection by doing the conversion to string format without allocating a new object.

15
  • 5
    Use mod and division to get the value of each digit. Commented Oct 25, 2013 at 16:59
  • please, add some code with what you have tried. Commented Oct 25, 2013 at 16:59
  • What's wrong with String? Commented Oct 25, 2013 at 17:01
  • Provide an example of what you are trying to do. Commented Oct 25, 2013 at 17:02
  • 3
    Follow this link : stackoverflow.com/questions/17575375/… It might be helpful for you Commented Oct 25, 2013 at 17:06

1 Answer 1

0

Thanks to @SLaks for the idea and @gypsoCoder for pointing me to a related answer. This does the trick:

  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;
     }
  }

I should note that this only accepts positive numbers and doesn't do any validation of that or anything else. Just a basic algorithm to accomplish the goal of converting a long to a string to a byte array without allocating any strings.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.