HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Build a double from a stream of chars

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
streamcharsdoublefrombuild

Problem

Back in my calculator post, janos suggested I either find a better way to read a double from a StreamReader or else go the whole way and build a double from scratch. I looked through a few streams, but the only one I found that supported reading a double was the BinaryReader. This, unfortunately, reads exactly 8 bytes, and the data is stored as a char (or rather, as an int representation of a char), so I could enter the equation "5+5", and it would crash when it read the "+". If you know of a better solution, I would prefer using it.

private double GetNextNumber(StreamReader dataStream)
{
    double value = 0;
    int decimalLevel = 0;

    while (true)
    {
        if (!"0123456789.".Contains((char)dataStream.Peek()))
        {
            break;
        }
        char token = (char)dataStream.Read();

        if (token == '.')
        {
            if (decimalLevel == 0)
            {
                ++decimalLevel;
                continue;
            }
            throw new InvalidDataException("Invalid number format.");
        }

        int digit = int.Parse(token.ToString());

        value = value * 10 + digit;

        if (decimalLevel != 0)
        {
            ++decimalLevel;
        }
    }

    return value / Math.Pow(10, decimalLevel - 1);  // use "- 1" because value increments just before ending loop
}


Please analyze my code as thoroughly as the compiler does.

Solution

You should avoid while (true) { … } loops wherever it is possible to do so. Here, it's very obviously avoidable!

while ("0123456789.".Contains((char)dataStream.Peek()))
{
    …
}


This parser leaves much to be desired in terms of handling

  • negative numbers (or you should document the fact that they are unsupported)



  • e notation for powers of ten



  • overflow and small numbers, due to excessive multiplying and dividing by powers of ten



Personally, I would avoid the entire headache by appending all plausible-looking characters to a StringBuilder, then calling double.Parse(string).

Code Snippets

while ("0123456789.".Contains((char)dataStream.Peek()))
{
    …
}

Context

StackExchange Code Review Q#88665, answer score: 7

Revisions (0)

No revisions yet.