Lawo.EmberPlusSharp.Ember.EmberWriter.WriteReal C# (CSharp) Method

WriteReal() private static method

See "X.690"X.690, chapter 8.5 and IEEE Floating-Point Representation. Of course the assumption is that C# has the same floating point representation as C++ (pretty safe, as floating point calculations are done by the hardware).
private static WriteReal ( WriteBuffer writeBuffer, double value ) : void
writeBuffer WriteBuffer
value double
return void
        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
        }