public static double DecodeReal(IBerInput input, int length)
{
double value = 0;
if(length != 0)
{
byte preamble = input.ReadByte();
if(length == 1 && preamble == 0x40) // positive infinity
{
value = double.PositiveInfinity;
}
else if(length == 1 && preamble == 0x41) // negative infinity
{
value = double.NegativeInfinity;
}
else if (length == 1 && preamble == 0x42) // not a number
{
value = double.NaN;
}
else
{
long longValue;
int exponentLength = 1 + (preamble & 3);
int sign = preamble & 0x40;
int ff = (preamble >> 2) & 3;
// Unpack mantissa & decrement exponent for base 2
long exponent = DecodeLong(input, exponentLength);
long mantissa = DecodeLong(input, length - exponentLength - 1, false) << ff;
// de-normalize mantissa (required by CER and DER)
while ((mantissa & 0x7FFFF00000000000L) == 0x0)
mantissa <<= 8;
while ((mantissa & 0x7FF0000000000000L) == 0x0)
mantissa <<= 1;
mantissa &= 0x0FFFFFFFFFFFFFL;
longValue = (exponent + 1023) << 52;
longValue |= mantissa;
if (sign != 0)
{
ulong qword = (ulong)longValue | 0x8000000000000000UL;
longValue = (long)qword;
}
value = Int64BitsToDouble((long)longValue);
}
}
return value;
}