in FixAntenna/NetCore/Message/Format/DoubleFormatter.cs [237:414]
public static int GetRequiredFormattedLength(double d, int extPrecision)
{
var length = 0;
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)
{
length++;
}
if (exp == 0 && mantissa == 0)
{
length++;
return length;
}
if (exp == 0x7ff)
{
if (mantissa == 0)
{
length += "Infinity".Length;
}
else
{
length += "NaN".Length;
}
return length;
}
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;
length += GetIntLength(intValue);
//sb.append(intValue);
mantissa -= intValue << shift;
if (mantissa > 0)
{
length++;
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)
{
return length;
}
length++;
mantissa -= num << precision;
var parsedValue = AsDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d)
{
break;
}
}
}
return length;
}
{
// faction.
length += 2;
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 length;
}
length++;
continue;
}
var num = (long)((ulong)mantissa >> precision);
value = value * 10 + num;
if (++decimalCount > extPrecision)
{
return length;
}
var c = (byte)('0' + num);
Debug.Assert(!(c < (byte)'0' || c > (byte)'9'));
length++;
mantissa -= num << precision;
var parsedValue = AsDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d)
{
break;
}
}
return length;
}
}
// 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);
length += GetIntLength(val2);
for (var i = 0; i < digits; i++)
{
length++;
}
return length;
}