|
// 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;
}
}
}
|