Tuesday, May 29, 2012

Strings to numbers

As I'm working away on my program, sans STL, I realized that I have a need to read a file and use the data within for various means. However this presented a problem because I didn't have a string to number converter, and as I didn't want to use STL I would need to write one.

Researching the problem of string to floats I found out just how complicated the issue could get. To do things properly the function needs to be able to handle all manner of different inputs, and still produce a useable float, naturally. But looking at strings and how error prone they can be that's where the real challenge lays I thought.

I did find online documentation that broke the problem down into a very handy intermediate step by using a so called "triad", or an int array with three elements: [sign][number][exponent], and as long as these three are populated properly, reconstructing the float is trivial. 

Started writing this I decided to put it in my string class to make use of it's functionality instead of in math or somewhere else, and that made things a bit easier.

First find either "nan" or "inf" and return the appropriate result, which in itself is rather interesting. How do you define a not-a-number, or infinite float? 0/0 isn't a number, but it won't compile either ;) It's only through cleaver casting of strange values is it achieved.

if(input.findTextNoCase("nan") >= 0)
{
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
return (*(const float *) __nan);
}

if(input.findTextNoCase("inf") >= 0)
{
static const int value = 0x7f800000;
return *(float*)&value;
}
The rest involved locating the negative / positive sign, locating any exponents (is 'e' is present), and finally converting regular numeric characters into a number.

for(int i = 0; i < inLen; i++)
{
if(input.isNumeric(input[i]))
{
valueStruct[1] = (valueStruct[1] * 10) + charToInt(input[i]);
}
}

Finally as the last step it's all added and multiplied into the resulting float.

float result = int, if there is a negative sign multiply by -1, and if there is an exponent, either keep multiplying or dividing by 10 until the necessary value is reached. Now while my method probably won't handle everything that gets thrown at it, I just need it to handle values I give it, and it seems to do that without problem, woot! 

Thats it for now! :)

No comments:

Post a Comment