示例#1
0
        public static unsafe float HalfToFloat(ushort value)
        {
            const ushort ExponentMask     = 0x7C00;
            const ushort ExponentShift    = 10;
            const ushort SignificandMask  = 0x03FF;
            const ushort SignificandShift = 0;
            const ushort MaxExponent      = 0x1F;

            bool sign = (short)value < 0;
            int  exp  = (sbyte)((value & ExponentMask) >> ExponentShift);
            uint sig  = (ushort)((value & SignificandMask) >> SignificandShift);

            if (exp == MaxExponent)
            {
                if (sig != 0)
                {
                    return(CreateSingleNaN(sign, (ulong)sig << 54));
                }
                return(sign ? float.NegativeInfinity : float.PositiveInfinity);
            }

            if (exp == 0)
            {
                if (sig == 0)
                {
                    return(CborHelpers.UInt32BitsToSingle(sign ? FloatSignMask : 0)); // Positive / Negative zero
                }
                (exp, sig) = NormSubnormalF16Sig(sig);
                exp       -= 1;
            }

            return(CreateSingle(sign, (byte)(exp + 0x70), sig << 13));
示例#2
0
        /// <summary>Reads the next data item as a double-precision floating point number (major type 7).</summary>
        /// <returns>The decoded <see cref="double" /> value.</returns>
        /// <exception cref="InvalidOperationException"><para>The next data item does not have the correct major type.</para>
        /// <para>-or-</para>
        /// <para>The next simple value is not a floating-point number encoding.</para></exception>
        /// <exception cref="CborContentException"><para>The next value has an invalid CBOR encoding.</para>
        /// <para>-or-</para>
        /// <para>There was an unexpected end of CBOR encoding data.</para>
        /// <para>-or-</para>
        /// <para>The next value uses a CBOR encoding that is not valid under the current conformance mode.</para></exception>
        public double ReadDouble()
        {
            CborInitialByte     header = PeekInitialByte(expectedType: CborMajorType.Simple);
            ReadOnlySpan <byte> buffer = GetRemainingBytes();
            double result;

            switch (header.AdditionalInfo)
            {
            case CborAdditionalInfo.Additional16BitData:
                EnsureReadCapacity(buffer, 1 + sizeof(short));
                result = HalfHelpers.HalfToDouble(CborHelpers.ReadHalfBigEndian(buffer.Slice(1)));
                AdvanceBuffer(1 + sizeof(short));
                AdvanceDataItemCounters();
                return(result);

            case CborAdditionalInfo.Additional32BitData:
                EnsureReadCapacity(buffer, 1 + sizeof(float));
                result = CborHelpers.ReadSingleBigEndian(buffer.Slice(1));
                AdvanceBuffer(1 + sizeof(float));
                AdvanceDataItemCounters();
                return(result);

            case CborAdditionalInfo.Additional64BitData:
                EnsureReadCapacity(buffer, 1 + sizeof(double));
                result = CborHelpers.ReadDoubleBigEndian(buffer.Slice(1));
                AdvanceBuffer(1 + sizeof(double));
                AdvanceDataItemCounters();
                return(result);

            default:
                throw new InvalidOperationException(SR.Cbor_Reader_NotAFloatEncoding);
            }
        }
示例#3
0
 private void WriteDoubleCore(double value)
 {
     EnsureWriteCapacity(1 + sizeof(double));
     WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional64BitData));
     CborHelpers.WriteDoubleBigEndian(_buffer.AsSpan(_offset), value);
     _offset += sizeof(double);
     AdvanceDataItemCounters();
 }
示例#4
0
        /// <summary>Writes the provided value as a tagged bignum encoding, as described in RFC7049 section 2.4.2.</summary>
        /// <param name="value">The value to write.</param>
        /// <exception cref="InvalidOperationException"><para>Writing a new value exceeds the definite length of the parent data item.</para>
        /// <para>-or-</para>
        /// <para>The major type of the encoded value is not permitted in the parent data item.</para>
        /// <para>-or-</para>
        /// <para>The written data is not accepted under the current conformance mode.</para></exception>
        public void WriteBigInteger(BigInteger value)
        {
            bool       isUnsigned    = value.Sign >= 0;
            BigInteger unsignedValue = isUnsigned ? value : -1 - value;

            byte[] unsignedBigEndianEncoding = CborHelpers.CreateUnsignedBigEndianBytesFromBigInteger(unsignedValue);

            WriteTag(isUnsigned ? CborTag.UnsignedBigNum : CborTag.NegativeBigNum);
            WriteByteString(unsignedBigEndianEncoding);
        }
示例#5
0
            /// reconstructs a decimal value out of a signed integral component and a negative base-10 exponent
            private static decimal ReconstructFromNegativeScale(decimal mantissa, byte scale)
            {
                Span <int> buf = stackalloc int[4];

                CborHelpers.GetBitsFromDecimal(mantissa, buf);

                int  flags      = buf[3];
                bool isNegative = (flags & SignMask) == SignMask;

                Debug.Assert((flags & ScaleMask) == 0, "mantissa argument should be integral.");
                return(new decimal(lo: buf[0], mid: buf[1], hi: buf[2], isNegative: isNegative, scale: scale));
            }
示例#6
0
            /// deconstructs a decimal value into its signed integral component and negative base-10 exponent
            public static void Deconstruct(decimal value, out decimal mantissa, out byte scale)
            {
                Span <int> buf = stackalloc int[4];

                CborHelpers.GetBitsFromDecimal(value, buf);

                int  flags      = buf[3];
                bool isNegative = (flags & SignMask) == SignMask;

                mantissa = new decimal(lo: buf[0], mid: buf[1], hi: buf[2], isNegative: isNegative, scale: 0);
                scale    = (byte)((flags & ScaleMask) >> ScaleShift);
            }
示例#7
0
 static float CreateSingle(bool sign, byte exp, uint sig)
 => CborHelpers.Int32BitsToSingle((int)(((sign ? 1U : 0U) << FloatSignShift) + ((uint)exp << FloatExponentShift) + sig));
 internal static bool TryConvertSingleToHalf(float value, out ushort result)
 {
     result = HalfHelpers.FloatToHalf(value);
     return(CborHelpers.SingleToInt32Bits(HalfHelpers.HalfToFloat(result)) == CborHelpers.SingleToInt32Bits(value));
 }