in FixAntenna/NetCore/Message/Format/DoubleFormatter.cs [441:638]
public static int Format(double d, int extPrecision, byte[] buff, int offset)
{
var localOffset = offset;
var val = BitConverter.DoubleToInt64Bits(d);
var sign = (int)(long)((ulong)val >> 63);
var exp = (int)((long)((ulong)val >> 52) & 0x7ff);
var mantissa = val & ((1L << 52) - 1);
if (sign != 0)
{
buff[localOffset++] = (byte)'-';
}
if (exp == 0 && mantissa == 0)
{
buff[localOffset++] = (byte)'0';
return localOffset - offset;
}
if (exp == 0x7ff)
{
if (mantissa == 0)
{
buff[localOffset++] = (byte)'I';
buff[localOffset++] = (byte)'n';
buff[localOffset++] = (byte)'f';
buff[localOffset++] = (byte)'i';
buff[localOffset++] = (byte)'n';
buff[localOffset++] = (byte)'i';
buff[localOffset++] = (byte)'t';
buff[localOffset++] = (byte)'y';
}
else
{
buff[localOffset++] = (byte)'N';
buff[localOffset++] = (byte)'a';
buff[localOffset++] = (byte)'N';
}
return localOffset - offset;
}
if (exp > 0)
{
//set the 52 bit (means 1.xxxx) which is missed
mantissa += 1L << 52;
}
var shift = 1023 + 52 - exp;
if (shift > 0)
{
// integer and faction
if (shift < 53)
{
var intValue = mantissa >> shift;
localOffset = FormatInt(intValue, buff, localOffset);
//sb.append(intValue);
mantissa -= intValue << shift;
if (mantissa > 0)
{
buff[localOffset++] = (byte)'.';
var decimalCount = 0;
mantissa <<= 1;
mantissa++;
var precision = shift + 1;
long error = 1;
var value = intValue;
var decimalPlaces = 0;
while (mantissa > error)
{
// times 5*2 = 10
mantissa *= 5;
error *= 5;
precision--;
var num = mantissa >> precision;
value = value * 10 + num;
if (++decimalCount > extPrecision)
{
if (num >= 5)
{
return RoundUpFormatted(buff, offset, localOffset - offset);
}
return CleanFormatted(buff, offset, localOffset - offset);
}
buff[localOffset++] = (byte)('0' + num);
mantissa -= num << precision;
var parsedValue = AsDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d)
{
break;
}
}
}
return localOffset - offset;
}
{
// faction.
buff[localOffset++] = (byte)'0';
buff[localOffset++] = (byte)'.';
var decimalCount = 0;
mantissa <<= 6;
mantissa += 1 << 5;
var precision = shift + 6;
//precision = 16;
long error = 1 << 5;
long value = 0;
var decimalPlaces = 0;
while (mantissa > error)
{
while (mantissa > MaxValueDivide5)
{
mantissa = (long)((ulong)mantissa >> 1);
error = (long)((ulong)(error + 1) >> 1);
precision--;
}
// times 5*2 = 10
mantissa *= 5;
error *= 5;
precision--;
if (precision >= 64)
{
if (++decimalCount > extPrecision)
{
return CleanFormatted(buff, offset, localOffset - offset);
}
buff[localOffset++] = (byte)'0';
continue;
}
var num = (long)((ulong)mantissa >> precision);
value = value * 10 + num;
if (++decimalCount > extPrecision)
{
if (num >= 5)
{
return RoundUpFormatted(buff, offset, localOffset - offset);
}
return CleanFormatted(buff, offset, localOffset - offset);
}
var c = (byte)('0' + num);
Debug.Assert(!(c < (byte)'0' || c > (byte)'9'));
buff[localOffset++] = c;
mantissa -= num << precision;
var parsedValue = AsDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d)
{
break;
}
}
return localOffset - offset;
}
}
// large number
mantissa <<= 10;
var precision1 = -10 - shift;
var digits = 0;
while ((precision1 > 53 || mantissa > long.MaxValue >> precision1) && precision1 > 0)
{
digits++;
precision1--;
var mod = mantissa % 5;
mantissa /= 5;
var modDiv = 1;
while (mantissa < MaxValueDivide5 && precision1 > 1)
{
precision1 -= 1;
mantissa <<= 1;
modDiv <<= 1;
}
mantissa += modDiv * mod / 5;
}
var val2 = precision1 > 0 ? mantissa << precision1 : (long)((ulong)mantissa >> -precision1);
localOffset = FormatInt(val2, buff, localOffset);
for (var i = 0; i < digits; i++)
{
buff[localOffset++] = (byte)'0';
}
return localOffset - offset;
}