DevBlogs
June 29th, 2015

# Parsing a string as a 64-bit integer, somehow

Today’s Little Program takes a string and tries to parse it as a 64-bit integer in formats that a programmer would likely encounter.

Here’s a first stab:

```using System;
using System.Globalization;

class Program
{
static long ParseLongSomehow(string s)
{
if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) {
return long.Parse(s.Substring(2), NumberStyles.HexNumber);
} else {
return long.Parse(s);
}
}

public static void Main(string[] args)
{
long value = ParseLongSomehow(args[0]);
Console.WriteLine(value);
Console.WriteLine("0x{0:X}", value);
}
}
```

If the string begins with `0x`, then we treat the rest of the argument as a hex value; otherwise, we treat it as a decimal value.

Unfortunately, this doesn’t work if the input is `9223372036854775808`, which is the value of `1 << 63`, a value that is representable as a 64-bit unsigned value but not a 64-bit signed value.

Our problem statement was pretty vague, so let’s write a functional specification. It helps to know what problem you’re solving before you start to solve it. Otherwise, you’re just flailing around writing code before you have a plan. When I tried to solve this problem, I flailed around a bit until I realized that I didn’t have a spec.

What formats would a programmer be likely to encounter as the string representation of a 64-bit integer?

• `0x1234`: 64-bit number in hex format, case-insensitive. The value can range from 0 to `UInt64.MaxValue`.
• `12345`: 64-bit unsigned number in decimal format. The value can range from 0 to `UInt64.MaxValue`.
• `-12345`: 64-bit signed number in decimal format. The value can range from `Int64.MinValue` to `Int64.MaxValue`.
• Other formats may be permitted, but you need to support at least the above.

Writing down exactly what I was doing and what I wasn’t doing was the part that solved my flailing. I had been worrying about things like `-0x12345` and `-9223372036854775809` and `9999999999999999999`, even though those numbers would not be something a programmer would be likely to encounter.

From the specification we can develop our algorithm.

• If the string begins with `0x`, then parse what’s left as an unsigned 64-bit hexadecimal number.
• If the string begins with a minus sign, then parse it as a 64-bit signed number in decimal format.
• If the string does not begin with a minus sign, then parse it as a 64-bit unsigned number in decimal format.

And that is pretty easy to implement.

``` static long ParseLongSomehow(string s)
{
if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) {
return long.Parse(s.Substring(2), NumberStyles.HexNumber);
} else if (s[0] == '-') {
return long.Parse(s);
} else {
return (long)ulong.Parse(s);
}
}
```

Note that we are a little sloppy with our treatment of whitespace. We accept leading and trailing spaces on decimal values, and allow trailing spaces on hex values (and even allow spaces between the `0x` and the first hex digit). That’s okay, because the spec allows us to accept formats beyond the ones listed.

Now, for bonus points, let’s revise the functional specification a little bit, specifically by adding another case:

• `0x12`3456789A`: 64-bit number in hex format, case-insensitive, with backtick separating the upper 32 bits from the lower 32 bits.

This is the format used by the Windows debugger engine.

``` static long ParseLongSomehow(string s)
{
if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) {
return long.Parse(s.Substring(2).Replace("`", ""), NumberStyles.HexNumber);
} else if (s[0] == '-') {
return long.Parse(s);
} else {
return (long)ulong.Parse(s);
}
}
```

We’ll leave it here for now. Next time, we’ll start putting some blocks together.

Topics
Code

## Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.