public static int WriteToChars(this float value, char[] str, int position)
{
int pos = position;
if (str.Length - position < 32)
throw new Exception("Insufficient buffer space");
if (Single.IsNaN(value))
{
str[0] = 'n';
str[1] = 'a';
str[2] = 'n';
return 3;
}
if (Single.IsNegativeInfinity(value))
{
str[0] = 'n';
str[1] = 'a';
str[2] = 'n';
return 3;
}
if (Single.IsPositiveInfinity(value))
{
str[0] = 'n';
str[1] = 'a';
str[2] = 'n';
return 3;
}
if (value == 0)
{
str[0] = '0';
return 1;
}
//Any number outside of this range will take the exponent form,
// and I'd rather not have to deal with this.
const float MaxValue = (9999999f);
const float MinValue = (-9999999f);
const float ZeroMax = (0.0001f);
const float ZeroMin = (-0.0001f);
if (value > MaxValue || value < MinValue || (value < ZeroMax && value > ZeroMin))
{
//Not worth coding for this case.
var T = value.ToString();
for (int x = 0; x < T.Length; x++)
{
str[pos + x] = T[pos + x];
}
return T.Length;
}
if (value < 0)
{
str[pos] = '-';
value = -value;
pos++;
}
int r = (value >= 999999.5f) ? 7 : (value >= 99999.95f) ? 6 : (value >= 9999.995f) ? 5 :
(value >= 999.9995f) ? 4 : (value >= 99.99995f) ? 3 : (value >= 9.999995f) ? 2 :
(value >= 0.9999995f) ? 1 : (value >= 0.09999995f) ? 0 : (value >= 0.009999995f) ? -1 :
(value >= 0.0009999995f) ? -2 : -3;
int wholePrecision = r;
int fracPrecision = 7 - r;
double scaled = (double)value * PowersOf10d[fracPrecision];
uint number = (uint)(scaled);
//Do the rounding
double fraction = (scaled - number);
if (fraction >= 0.5)
{
//Round
number++;
}
//Write the number
ulong bcd = BinToReverseBCD(number);
if (wholePrecision <= 0)
{
str[pos++] = '0';
str[pos++] = '.';
while (wholePrecision < 0)
{
str[pos++] = '0';
wholePrecision++;
}
}
else
{
while (wholePrecision > 0)
{
wholePrecision--;
str[pos++] = (char)(48 + (bcd & 0xf));
bcd >>= 4;
}
if (bcd == 0)
return pos - position;
str[pos++] = '.';
}
while (bcd != 0)
{
str[pos++] = (char)(48 + (bcd & 0xf));
bcd >>= 4;
}
return pos - position;
}