public static DecodeReal ( IBerInput input, int length ) : double | ||
input | IBerInput | |
length | int | |
return | double |
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;
}
/// <summary> /// Decodes the value of the current TLV as double. /// Throws an exception in case of a format mismatch. /// </summary> /// <returns>The double value of the current TLV.</returns> public double GetReal() { if (IsContainer) { ThrowError(204, "Invalid Real encoding"); } Debug.Assert(Value != null || Length == 0); Debug.Assert(Type == BerType.Real || BerType.IsApplicationDefined(Type)); var input = new BerMemoryInput(Value); return(BerEncoding.DecodeReal(input, Length)); }