numberToString fails in the int64 corner cases


#1
static char* numberToString (char* t, const int64 n) noexcept

Doesn’t correctly handle the case where n = std::numeric_limits ::min().

A unit test would have discovered this. Here’s part my unit test for my version of lexicalCast which calls the String constructor for int64 as needed:

String s;
s << "numeric_limits <" << typeid (IntType).name () << ">";
beginTestCase (s);

testInteger (std::numeric_limits <IntType>::min ());
testInteger (std::numeric_limits <IntType>::max ());

#2

Turns out these simple operations are tricky as FUNK!!! Anyway…this is what I managed to come up with. It’s really easy to make a mistake and wind up with Undefined Behavior (for example its undefined to write - std::numeric_limits::min()

Here’s the replacement. I know Jules will complain, but it passes all my unit tests:

// pass in a pointer to the END of a buffer..
static char* numberToString (char* t, const int64 n) noexcept
{
    if (n > 0)
    {
        *--t = 0;
        uint64 v = static_cast <uint64> (n);

        do
        {
            *--t = (char) ('0' + (int) (v % 10));
            v /= 10;

        }
        while (v > 0);
    }
    else
    {
        *--t = 0;
        uint64 v = ((uint64)(-(n + 1)) + 1);

        do
        {
            *--t = (char) ('0' + (int) (v % 10));
            v /= 10;

        }
        while (v > 0);

        *--t = '-';
    }

    return t;
}

#3

Thanks Vinnie! Those methods did need a bit of cleaning-up, but I think they should cope with all the edge-cases now. I’ve added a few more unit tests for them to make sure.