File: src\libraries\System.Private.CoreLib\src\System\Numerics\IFloatingPoint.cs
Web Access
Project: src\src\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj (System.Private.CoreLib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System.Numerics
{
    /// <summary>Defines a floating-point type.</summary>
    /// <typeparam name="TSelf">The type that implements the interface.</typeparam>
    public interface IFloatingPoint<TSelf>
        : IFloatingPointConstants<TSelf>,
          INumber<TSelf>,
          ISignedNumber<TSelf>
        where TSelf : IFloatingPoint<TSelf>?
    {
        /// <summary>Computes the ceiling of a value.</summary>
        /// <param name="x">The value whose ceiling is to be computed.</param>
        /// <returns>The ceiling of <paramref name="x" />.</returns>
        static virtual TSelf Ceiling(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToPositiveInfinity);
 
        /// <summary>Converts a value to a specified integer type using saturation on overflow</summary>
        /// <typeparam name="TInteger">The integer type to which <paramref name="value" /> is converted.</typeparam>
        /// <param name="value">The value to be converted.</param>
        /// <returns>An instance of <typeparamref name="TInteger" /> created from <paramref name="value" />.</returns>
        static virtual TInteger ConvertToInteger<TInteger>(TSelf value)
            where TInteger : IBinaryInteger<TInteger>
        {
            return TInteger.CreateSaturating(value);
        }
 
        /// <summary>Converts a value to a specified integer type using platform specific behavior on overflow.</summary>
        /// <typeparam name="TInteger">The integer type to which <paramref name="value" /> is converted.</typeparam>
        /// <param name="value">The value to be converted.</param>
        /// <returns>An instance of <typeparamref name="TInteger" /> created from <paramref name="value" />.</returns>
        static virtual TInteger ConvertToIntegerNative<TInteger>(TSelf value)
            where TInteger : IBinaryInteger<TInteger>
        {
            return TSelf.ConvertToInteger<TInteger>(value);
        }
 
        /// <summary>Computes the floor of a value.</summary>
        /// <param name="x">The value whose floor is to be computed.</param>
        /// <returns>The floor of <paramref name="x" />.</returns>
        static virtual TSelf Floor(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToNegativeInfinity);
 
        /// <summary>Rounds a value to the nearest integer using the default rounding mode (<see cref="MidpointRounding.ToEven" />).</summary>
        /// <param name="x">The value to round.</param>
        /// <returns>The result of rounding <paramref name="x" /> to the nearest integer using the default rounding mode.</returns>
        static virtual TSelf Round(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToEven);
 
        /// <summary>Rounds a value to a specified number of fractional-digits using the default rounding mode (<see cref="MidpointRounding.ToEven" />).</summary>
        /// <param name="x">The value to round.</param>
        /// <param name="digits">The number of fractional digits to which <paramref name="x" /> should be rounded.</param>
        /// <returns>The result of rounding <paramref name="x" /> to <paramref name="digits" /> fractional-digits using the default rounding mode.</returns>
        static virtual TSelf Round(TSelf x, int digits) => TSelf.Round(x, digits, MidpointRounding.ToEven);
 
        /// <summary>Rounds a value to the nearest integer using the specified rounding mode.</summary>
        /// <param name="x">The value to round.</param>
        /// <param name="mode">The mode under which <paramref name="x" /> should be rounded.</param>
        /// <returns>The result of rounding <paramref name="x" /> to the nearest integer using <paramref name="mode" />.</returns>
        static virtual TSelf Round(TSelf x, MidpointRounding mode) => TSelf.Round(x, digits: 0, mode);
 
        /// <summary>Rounds a value to a specified number of fractional-digits using the specified rounding mode.</summary>
        /// <param name="x">The value to round.</param>
        /// <param name="digits">The number of fractional digits to which <paramref name="x" /> should be rounded.</param>
        /// <param name="mode">The mode under which <paramref name="x" /> should be rounded.</param>
        /// <returns>The result of rounding <paramref name="x" /> to <paramref name="digits" /> fractional-digits using <paramref name="mode" />.</returns>
        static abstract TSelf Round(TSelf x, int digits, MidpointRounding mode);
 
        /// <summary>Truncates a value.</summary>
        /// <param name="x">The value to truncate.</param>
        /// <returns>The truncation of <paramref name="x" />.</returns>
        static virtual TSelf Truncate(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToZero);
 
        /// <summary>Gets the number of bytes that will be written as part of <see cref="TryWriteExponentLittleEndian(Span{byte}, out int)" />.</summary>
        /// <returns>The number of bytes that will be written as part of <see cref="TryWriteExponentLittleEndian(Span{byte}, out int)" />.</returns>
        int GetExponentByteCount();
 
        /// <summary>Gets the length, in bits, of the shortest two's complement representation of the current exponent.</summary>
        /// <returns>The length, in bits, of the shortest two's complement representation of the current exponent.</returns>
        int GetExponentShortestBitLength();
 
        /// <summary>Gets the length, in bits, of the current significand.</summary>
        /// <returns>The length, in bits, of the current significand.</returns>
        int GetSignificandBitLength();
 
        /// <summary>Gets the number of bytes that will be written as part of <see cref="TryWriteSignificandLittleEndian(Span{byte}, out int)" />.</summary>
        /// <returns>The number of bytes that will be written as part of <see cref="TryWriteSignificandLittleEndian(Span{byte}, out int)" />.</returns>
        int GetSignificandByteCount();
 
        /// <summary>Tries to write the current exponent, in big-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current exponent should be written.</param>
        /// <param name="bytesWritten">The number of bytes written to <paramref name="destination" />.</param>
        /// <returns><c>true</c> if the exponent was successfully written to <paramref name="destination" />; otherwise, <c>false</c>.</returns>
        bool TryWriteExponentBigEndian(Span<byte> destination, out int bytesWritten);
 
        /// <summary>Tries to write the current exponent, in little-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current exponent should be written.</param>
        /// <param name="bytesWritten">The number of bytes written to <paramref name="destination" />.</param>
        /// <returns><c>true</c> if the exponent was successfully written to <paramref name="destination" />; otherwise, <c>false</c>.</returns>
        bool TryWriteExponentLittleEndian(Span<byte> destination, out int bytesWritten);
 
        /// <summary>Tries to write the current significand, in big-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current significand should be written.</param>
        /// <param name="bytesWritten">The number of bytes written to <paramref name="destination" />.</param>
        /// <returns><c>true</c> if the significand was successfully written to <paramref name="destination" />; otherwise, <c>false</c>.</returns>
        bool TryWriteSignificandBigEndian(Span<byte> destination, out int bytesWritten);
 
        /// <summary>Tries to write the current significand, in little-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current significand should be written.</param>
        /// <param name="bytesWritten">The number of bytes written to <paramref name="destination" />.</param>
        /// <returns><c>true</c> if the significand was successfully written to <paramref name="destination" />; otherwise, <c>false</c>.</returns>
        bool TryWriteSignificandLittleEndian(Span<byte> destination, out int bytesWritten);
 
        /// <summary>Writes the current exponent, in big-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteExponentBigEndian(byte[] destination)
        {
            if (!TryWriteExponentBigEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current exponent, in big-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current exponent should be written.</param>
        /// <param name="startIndex">The starting index at which the exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" /> starting at <paramref name="startIndex" />.</returns>
        int WriteExponentBigEndian(byte[] destination, int startIndex)
        {
            if (!TryWriteExponentBigEndian(destination.AsSpan(startIndex), out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current exponent, in big-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteExponentBigEndian(Span<byte> destination)
        {
            if (!TryWriteExponentBigEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current exponent, in little-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteExponentLittleEndian(byte[] destination)
        {
            if (!TryWriteExponentLittleEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current exponent, in little-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current exponent should be written.</param>
        /// <param name="startIndex">The starting index at which the exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" /> starting at <paramref name="startIndex" />.</returns>
        int WriteExponentLittleEndian(byte[] destination, int startIndex)
        {
            if (!TryWriteExponentLittleEndian(destination.AsSpan(startIndex), out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current exponent, in little-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current exponent should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteExponentLittleEndian(Span<byte> destination)
        {
            if (!TryWriteExponentLittleEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in big-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteSignificandBigEndian(byte[] destination)
        {
            if (!TryWriteSignificandBigEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in big-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current significand should be written.</param>
        /// <param name="startIndex">The starting index at which the significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" /> starting at <paramref name="startIndex" />.</returns>
        int WriteSignificandBigEndian(byte[] destination, int startIndex)
        {
            if (!TryWriteSignificandBigEndian(destination.AsSpan(startIndex), out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in big-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteSignificandBigEndian(Span<byte> destination)
        {
            if (!TryWriteSignificandBigEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in little-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteSignificandLittleEndian(byte[] destination)
        {
            if (!TryWriteSignificandLittleEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in little-endian format, to a given array.</summary>
        /// <param name="destination">The array to which the current significand should be written.</param>
        /// <param name="startIndex">The starting index at which the significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" /> starting at <paramref name="startIndex" />.</returns>
        int WriteSignificandLittleEndian(byte[] destination, int startIndex)
        {
            if (!TryWriteSignificandLittleEndian(destination.AsSpan(startIndex), out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
 
        /// <summary>Writes the current significand, in little-endian format, to a given span.</summary>
        /// <param name="destination">The span to which the current significand should be written.</param>
        /// <returns>The number of bytes written to <paramref name="destination" />.</returns>
        int WriteSignificandLittleEndian(Span<byte> destination)
        {
            if (!TryWriteSignificandLittleEndian(destination, out int bytesWritten))
            {
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
            }
            return bytesWritten;
        }
    }
}