public static int GetRequiredFormattedLength()

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;
		}