private static void WriteReal(WriteBuffer writeBuffer, double value)
{
if (!BitConverter.IsLittleEndian)
{
throw new NotSupportedException("Method is not supported for big endian system.");
}
if (double.IsInfinity(value))
{
writeBuffer[writeBuffer.Count++] = (byte)(value > 0 ? 0x40 : 0x41); // 8.5.6 c) and 8.5.9
return;
}
if (double.IsNaN(value))
{
writeBuffer[writeBuffer.Count++] = 0x42; // 8.5.9
return;
}
var bits = BitConverter.DoubleToInt64Bits(value);
if (bits == NegativeZeroInteger)
{
writeBuffer[writeBuffer.Count++] = 0x43; // 8.5.3 and 8.5.9
return;
}
// 8.5.2
if (bits == 0)
{
return;
}
// 8.5.6 a)
byte firstContentsOctet = 0x80;
const long SignMask = long.MinValue;
// 8.5.7.1
if ((bits & SignMask) != 0)
{
firstContentsOctet |= 0x40;
}
var exponent =
((bits & Constants.DoubleExponentMask) >> Constants.DoubleMantissaBits) - Constants.DoubleExponentBias;
var exponentShift = Get8BitStartShift(exponent, true);
firstContentsOctet |= (byte)(GetLengthFromShift8Bit(exponentShift) - 1); // 8.5.7.4
writeBuffer[writeBuffer.Count++] = firstContentsOctet;
Write8Bit(writeBuffer, exponent, exponentShift);
const long MantissaAssumedLeadingOne = 1L << Constants.DoubleMantissaBits;
var mantissa = (bits & Constants.DoubleMantissaMask) | MantissaAssumedLeadingOne;
// CER denormalization 11.3.1 (not required but saves space)
while ((mantissa & 0xFF) == 0)
{
mantissa >>= Constants.BitsPerByte;
}
while ((mantissa & 0x01) == 0)
{
mantissa >>= 1;
}
// TODO: According to 8.5.7.5 we should pass false below, but we pass true to avoid a bug in EmberLib.
Write8Bit(writeBuffer, mantissa, Get8BitStartShift(mantissa, true)); // 8.5.6.5
}