diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index 3e91b3ecb8340..4a8f63df47f24 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -4331,6 +4331,9 @@
Emitting debug info is not supported for this member.
+
+ Object must be of type BFloat16.
+
The specified type must be a reference type, a primitive type, or an enum type.
diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 2fdf95932689b..49bc04768b267 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -595,6 +595,7 @@
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs
index dab5e73a27887..432926f6b1369 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Half.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs
@@ -738,8 +738,8 @@ public static explicit operator Half(float value)
const uint SingleBiasedExponentMask = float.BiasedExponentMask;
// Exponent displacement #2
const uint Exponent13 = 0x0680_0000u;
- // Maximum value that is not Infinity in Half
- const float MaxHalfValueBelowInfinity = 65520.0f;
+ // The value above Half.MaxValue
+ const float HalfAboveMaxValue = 65520.0f;
// Mask for exponent bits in Half
const uint ExponentMask = BiasedExponentMask;
uint bitValue = BitConverter.SingleToUInt32Bits(value);
@@ -750,7 +750,7 @@ public static explicit operator Half(float value)
// Clear sign bit
value = float.Abs(value);
// Rectify values that are Infinity in Half. (float.Min now emits vminps instruction if one of two arguments is a constant)
- value = float.Min(MaxHalfValueBelowInfinity, value);
+ value = float.Min(HalfAboveMaxValue, value);
// Rectify lower exponent
uint exponentOffset0 = BitConverter.SingleToUInt32Bits(float.Max(value, BitConverter.UInt32BitsToSingle(MinExp)));
// Extract exponent
@@ -1362,7 +1362,7 @@ int IFloatingPoint.GetExponentShortestBitLength()
int IFloatingPoint.GetSignificandByteCount() => sizeof(ushort);
///
- int IFloatingPoint.GetSignificandBitLength() => 11;
+ int IFloatingPoint.GetSignificandBitLength() => SignificandLength;
///
bool IFloatingPoint.TryWriteExponentBigEndian(Span destination, out int bytesWritten)
@@ -2311,7 +2311,7 @@ public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFo
static int IBinaryFloatParseAndFormatInfo.NumberBufferLength => Number.HalfNumberBufferLength;
static ulong IBinaryFloatParseAndFormatInfo.ZeroBits => 0;
- static ulong IBinaryFloatParseAndFormatInfo.InfinityBits => 0x7C00;
+ static ulong IBinaryFloatParseAndFormatInfo.InfinityBits => PositiveInfinityBits;
static ulong IBinaryFloatParseAndFormatInfo.NormalMantissaMask => (1UL << SignificandLength) - 1;
static ulong IBinaryFloatParseAndFormatInfo.DenormalMantissaMask => TrailingSignificandMask;
@@ -2323,15 +2323,15 @@ public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFo
static int IBinaryFloatParseAndFormatInfo.MaxDecimalExponent => 5;
static int IBinaryFloatParseAndFormatInfo.ExponentBias => ExponentBias;
- static ushort IBinaryFloatParseAndFormatInfo.ExponentBits => 5;
+ static ushort IBinaryFloatParseAndFormatInfo.ExponentBits => BiasedExponentLength;
static int IBinaryFloatParseAndFormatInfo.OverflowDecimalExponent => (MaxExponent + (2 * SignificandLength)) / 3;
- static int IBinaryFloatParseAndFormatInfo.InfinityExponent => 0x1F;
+ static int IBinaryFloatParseAndFormatInfo.InfinityExponent => MaxBiasedExponent;
static ushort IBinaryFloatParseAndFormatInfo.NormalMantissaBits => SignificandLength;
static ushort IBinaryFloatParseAndFormatInfo.DenormalMantissaBits => TrailingSignificandLength;
- static int IBinaryFloatParseAndFormatInfo.MinFastFloatDecimalExponent => -8;
+ static int IBinaryFloatParseAndFormatInfo.MinFastFloatDecimalExponent => -26;
static int IBinaryFloatParseAndFormatInfo.MaxFastFloatDecimalExponent => 4;
static int IBinaryFloatParseAndFormatInfo.MinExponentRoundToEven => -21;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
index bb80ebd3ff67a..8faf707afcc09 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
@@ -50,6 +50,9 @@ internal interface IBinaryIntegerParseAndFormatInfo : IBinaryInteger : IBinaryFloatingPointIeee754, IMinMaxValue
where TSelf : unmanaged, IBinaryFloatParseAndFormatInfo
{
+ ///
+ /// Ceiling(Log10(5^(Abs(MinBinaryExponent) - 1))) + NormalMantissaBits + 1 + 1
+ ///
static abstract int NumberBufferLength { get; }
static abstract ulong ZeroBits { get; }
@@ -61,7 +64,14 @@ internal interface IBinaryFloatParseAndFormatInfo : IBinaryFloatingPointI
static abstract int MinBinaryExponent { get; }
static abstract int MaxBinaryExponent { get; }
+ ///
+ /// Floor(Log10(Epsilon))
+ ///
static abstract int MinDecimalExponent { get; }
+
+ ///
+ /// Ceiling(Log10(MaxValue))
+ ///
static abstract int MaxDecimalExponent { get; }
static abstract int ExponentBias { get; }
@@ -73,12 +83,29 @@ internal interface IBinaryFloatParseAndFormatInfo : IBinaryFloatingPointI
static abstract ushort NormalMantissaBits { get; }
static abstract ushort DenormalMantissaBits { get; }
+ ///
+ /// Ceiling(Log10(2^(MinBinaryExponent - 1 - DenormalMantissaBits - 64)))
+ ///
static abstract int MinFastFloatDecimalExponent { get; }
+
+ ///
+ /// MaxDecimalExponent - 1
+ ///
static abstract int MaxFastFloatDecimalExponent { get; }
+ ///
+ /// -Floor(Log5(2^(64 - NormalMantissaBits)))
+ ///
static abstract int MinExponentRoundToEven { get; }
+
+ ///
+ /// Floor(Log5(2^(NormalMantissaBits + 1)))
+ ///
static abstract int MaxExponentRoundToEven { get; }
+ ///
+ /// Max(n) when 10^n can be precisely represented
+ ///
static abstract int MaxExponentFastPath { get; }
static abstract ulong MaxMantissaFastPath { get; }
@@ -86,16 +113,23 @@ internal interface IBinaryFloatParseAndFormatInfo : IBinaryFloatingPointI
static abstract ulong FloatToBits(TSelf value);
- // Maximum number of digits required to guarantee that any given floating point
- // number can roundtrip. Some numbers may require less, but none will require more.
+ ///
+ /// Maximum number of digits required to guarantee that any given floating point
+ /// number can roundtrip. Some numbers may require less, but none will require more.
+ ///
+ ///
+ /// Ceiling(Log10(2^NormalMantissaBits)) + 1
+ ///
static abstract int MaxRoundTripDigits { get; }
- // SinglePrecisionCustomFormat and DoublePrecisionCustomFormat are used to ensure that
- // custom format strings return the same string as in previous releases when the format
- // would return x digits or less (where x is the value of the corresponding constant).
- // In order to support more digits, we would need to update ParseFormatSpecifier to pre-parse
- // the format and determine exactly how many digits are being requested and whether they
- // represent "significant digits" or "digits after the decimal point".
+ ///
+ /// MaxPrecisionCustomFormat is used to ensure that
+ /// custom format strings return the same string as in previous releases when the format
+ /// would return x digits or less (where x is the value of the corresponding constant).
+ /// In order to support more digits, we would need to update ParseFormatSpecifier to pre-parse
+ /// the format and determine exactly how many digits are being requested and whether they
+ /// represent "significant digits" or "digits after the decimal point".
+ ///
static abstract int MaxPrecisionCustomFormat { get; }
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/BFloat16.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/BFloat16.cs
new file mode 100644
index 0000000000000..04f5412fcbc52
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BFloat16.cs
@@ -0,0 +1,2011 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Buffers.Binary;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using static System.Reflection.Emit.TypeNameBuilder;
+
+namespace System.Numerics
+{
+ ///
+ /// Represents a shortened (16-bit) version of 32 bit floating-point value ().
+ ///
+ public readonly struct BFloat16
+ : IComparable,
+ ISpanFormattable,
+ IComparable,
+ IEquatable,
+ IBinaryFloatingPointIeee754,
+ IMinMaxValue,
+ IUtf8SpanFormattable,
+ IBinaryFloatParseAndFormatInfo
+ {
+ private const NumberStyles DefaultParseStyle = NumberStyles.Float | NumberStyles.AllowThousands;
+
+ // Constants for manipulating the private bit-representation
+
+ internal const ushort SignMask = 0x8000;
+ internal const int SignShift = 15;
+ internal const byte ShiftedSignMask = SignMask >> SignShift;
+
+ internal const ushort BiasedExponentMask = 0x7F80;
+ internal const int BiasedExponentShift = 7;
+ internal const int BiasedExponentLength = 8;
+ internal const byte ShiftedBiasedExponentMask = BiasedExponentMask >> BiasedExponentShift;
+
+ internal const ushort TrailingSignificandMask = 0x007F;
+
+ internal const byte MinSign = 0;
+ internal const byte MaxSign = 1;
+
+ internal const byte MinBiasedExponent = 0x00;
+ internal const byte MaxBiasedExponent = 0xFF;
+
+ internal const byte ExponentBias = 127;
+
+ internal const sbyte MinExponent = -126;
+ internal const sbyte MaxExponent = +127;
+
+ internal const ushort MinTrailingSignificand = 0x0000;
+ internal const ushort MaxTrailingSignificand = 0x007F;
+
+ internal const int TrailingSignificandLength = 7;
+ internal const int SignificandLength = TrailingSignificandLength + 1;
+
+ // Constants representing the private bit-representation for various default values
+
+ private const ushort PositiveZeroBits = 0x0000;
+ private const ushort NegativeZeroBits = 0x8000;
+
+ private const ushort EpsilonBits = 0x0001;
+
+ private const ushort PositiveInfinityBits = 0x7F80;
+ private const ushort NegativeInfinityBits = 0xFF80;
+
+ // private const ushort PositiveQNaNBits = 0x7FC0;
+ private const ushort NegativeQNaNBits = 0xFFC0;
+
+ private const ushort MinValueBits = 0xFF7F;
+ private const ushort MaxValueBits = 0x7F7F;
+
+ private const ushort PositiveOneBits = 0x3F80;
+ private const ushort NegativeOneBits = 0xBF80;
+
+ private const ushort SmallestNormalBits = 0x0080;
+
+ private const ushort EBits = 0x402E;
+ private const ushort PiBits = 0x4049;
+ private const ushort TauBits = 0x40C9;
+
+ // Well-defined and commonly used values
+
+ public static BFloat16 Epsilon => new BFloat16(EpsilonBits);
+
+ public static BFloat16 PositiveInfinity => new BFloat16(PositiveInfinityBits);
+
+ public static BFloat16 NegativeInfinity => new BFloat16(NegativeInfinityBits);
+
+ public static BFloat16 NaN => new BFloat16(NegativeQNaNBits);
+
+ ///
+ public static BFloat16 MinValue => new BFloat16(MinValueBits);
+
+ ///
+ public static BFloat16 MaxValue => new BFloat16(MaxValueBits);
+
+ internal readonly ushort _value;
+
+ internal BFloat16(ushort value) => _value = value;
+
+ internal byte BiasedExponent
+ {
+ get
+ {
+ ushort bits = _value;
+ return ExtractBiasedExponentFromBits(bits);
+ }
+ }
+
+ internal sbyte Exponent
+ {
+ get
+ {
+ return (sbyte)(BiasedExponent - ExponentBias);
+ }
+ }
+
+ internal ushort Significand
+ {
+ get
+ {
+ return (ushort)(TrailingSignificand | ((BiasedExponent != 0) ? (1U << BiasedExponentShift) : 0U));
+ }
+ }
+
+ internal ushort TrailingSignificand
+ {
+ get
+ {
+ ushort bits = _value;
+ return ExtractTrailingSignificandFromBits(bits);
+ }
+ }
+
+ internal static byte ExtractBiasedExponentFromBits(ushort bits)
+ {
+ return (byte)((bits >> BiasedExponentShift) & ShiftedBiasedExponentMask);
+ }
+
+ internal static ushort ExtractTrailingSignificandFromBits(ushort bits)
+ {
+ return (ushort)(bits & TrailingSignificandMask);
+ }
+
+ // INumberBase
+
+ /// Determines whether the specified value is finite (zero, subnormal, or normal).
+ /// This effectively checks the value is not NaN and not infinite.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsFinite(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (~bits & PositiveInfinityBits) != 0;
+ }
+
+ /// Determines whether the specified value is infinite.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsInfinity(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (bits & ~SignMask) == PositiveInfinityBits;
+ }
+
+ /// Determines whether the specified value is NaN.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNaN(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (bits & ~SignMask) > PositiveInfinityBits;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool IsNaNOrZero(BFloat16 value)
+ {
+ uint bits = value._value;
+ return ((bits - 1) & ~SignMask) >= PositiveInfinityBits;
+ }
+
+ /// Determines whether the specified value is negative.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNegative(BFloat16 value)
+ {
+ return (short)(value._value) < 0;
+ }
+
+ /// Determines whether the specified value is negative infinity.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNegativeInfinity(BFloat16 value)
+ {
+ return value._value == NegativeInfinityBits;
+ }
+
+ /// Determines whether the specified value is normal (finite, but not zero or subnormal).
+ /// This effectively checks the value is not NaN, not infinite, not subnormal, and not zero.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNormal(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (ushort)((bits & ~SignMask) - SmallestNormalBits) < (PositiveInfinityBits - SmallestNormalBits);
+ }
+
+ /// Determines whether the specified value is positive infinity.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsPositiveInfinity(BFloat16 value)
+ {
+ return value._value == PositiveInfinityBits;
+ }
+
+ /// Determines whether the specified value is subnormal (finite, but not zero or normal).
+ /// This effectively checks the value is not NaN, not infinite, not normal, and not zero.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsSubnormal(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (ushort)((bits & ~SignMask) - 1) < MaxTrailingSignificand;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsZero(BFloat16 value)
+ {
+ uint bits = value._value;
+ return (bits & ~SignMask) == 0;
+ }
+
+ ///
+ /// Parses a from a in the default parse style.
+ ///
+ /// The input to be parsed.
+ /// The equivalent value representing the input string. If the input exceeds BFloat16's range, a or is returned.
+ public static BFloat16 Parse(string s) => Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider: null);
+
+ ///
+ /// Parses a from a in the given .
+ ///
+ /// The input to be parsed.
+ /// The used to parse the input.
+ /// The equivalent value representing the input string. If the input exceeds BFloat16's range, a or is returned.
+ public static BFloat16 Parse(string s, NumberStyles style) => Parse(s, style, provider: null);
+
+ ///
+ /// Parses a from a and .
+ ///
+ /// The input to be parsed.
+ /// A format provider.
+ /// The equivalent value representing the input string. If the input exceeds BFloat16's range, a or is returned.
+ public static BFloat16 Parse(string s, IFormatProvider? provider) => Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider);
+
+ ///
+ /// Parses a from a with the given and .
+ ///
+ /// The input to be parsed.
+ /// The used to parse the input.
+ /// A format provider.
+ /// The equivalent value representing the input string. If the input exceeds BFloat16's range, a or is returned.
+ public static BFloat16 Parse(string s, NumberStyles style = DefaultParseStyle, IFormatProvider? provider = null)
+ {
+ if (s is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
+ }
+ return Parse(s.AsSpan(), style, provider);
+ }
+
+ ///
+ /// Parses a from a and .
+ ///
+ /// The input to be parsed.
+ /// The used to parse the input.
+ /// A format provider.
+ /// The equivalent value representing the input string. If the input exceeds BFloat16's range, a or is returned.
+ public static BFloat16 Parse(ReadOnlySpan s, NumberStyles style = DefaultParseStyle, IFormatProvider? provider = null)
+ {
+ NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
+ return Number.ParseFloat(s, style, NumberFormatInfo.GetInstance(provider));
+ }
+
+ ///
+ /// Tries to parse a from a in the default parse style.
+ ///
+ /// The input to be parsed.
+ /// The equivalent value representing the input string if the parse was successful. If the input exceeds BFloat16's range, a or is returned. If the parse was unsuccessful, a default value is returned.
+ /// if the parse was successful, otherwise.
+ public static bool TryParse([NotNullWhen(true)] string? s, out BFloat16 result) => TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider: null, out result);
+
+ ///
+ /// Tries to parse a from a in the default parse style.
+ ///
+ /// The input to be parsed.
+ /// The equivalent value representing the input string if the parse was successful. If the input exceeds BFloat16's range, a or is returned. If the parse was unsuccessful, a default value is returned.
+ /// if the parse was successful, otherwise.
+ public static bool TryParse(ReadOnlySpan s, out BFloat16 result) => TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider: null, out result);
+
+ /// Tries to convert a UTF-8 character span containing the string representation of a number to its number equivalent.
+ /// A read-only UTF-8 character span that contains the number to convert.
+ /// When this method returns, contains a number equivalent of the numeric value or symbol contained in if the conversion succeeded or zero if the conversion failed. The conversion fails if the is or is not in a valid format. This parameter is passed uninitialized; any value originally supplied in result will be overwritten.
+ /// true if was converted successfully; otherwise, false.
+ public static bool TryParse(ReadOnlySpan utf8Text, out BFloat16 result) => TryParse(utf8Text, NumberStyles.Float | NumberStyles.AllowThousands, provider: null, out result);
+
+ ///
+ /// Tries to parse a from a with the given and .
+ ///
+ /// The input to be parsed.
+ /// The used to parse the input.
+ /// A format provider.
+ /// The equivalent value representing the input string if the parse was successful. If the input exceeds BFloat16's range, a or is returned. If the parse was unsuccessful, a default value is returned.
+ /// if the parse was successful, otherwise.
+ public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out BFloat16 result)
+ {
+ NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
+
+ if (s == null)
+ {
+ result = Zero;
+ return false;
+ }
+ return Number.TryParseFloat(s.AsSpan(), style, NumberFormatInfo.GetInstance(provider), out result);
+ }
+
+ ///
+ /// Tries to parse a from a with the given and .
+ ///
+ /// The input to be parsed.
+ /// The used to parse the input.
+ /// A format provider.
+ /// The equivalent value representing the input string if the parse was successful. If the input exceeds BFloat16's range, a or is returned. If the parse was unsuccessful, a default value is returned.
+ /// if the parse was successful, otherwise.
+ public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out BFloat16 result)
+ {
+ NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
+ return Number.TryParseFloat(s, style, NumberFormatInfo.GetInstance(provider), out result);
+ }
+
+ // Comparison
+
+ ///
+ /// Compares this object to another object, returning an integer that indicates the relationship.
+ ///
+ /// A value less than zero if this is less than , zero if this is equal to , or a value greater than zero if this is greater than .
+ /// Thrown when is not of type .
+ public int CompareTo(object? obj)
+ {
+ if (obj is not BFloat16 other)
+ {
+ return (obj is null) ? 1 : throw new ArgumentException(SR.Arg_MustBeBFloat16);
+ }
+ return CompareTo(other);
+ }
+
+ ///
+ /// Compares this object to another object, returning an integer that indicates the relationship.
+ ///
+ /// A value less than zero if this is less than , zero if this is equal to , or a value greater than zero if this is greater than .
+ public int CompareTo(BFloat16 other) => ((float)this).CompareTo((float)other);
+
+ ///
+ public static bool operator ==(BFloat16 left, BFloat16 right) => (float)left == (float)right;
+
+ ///
+ public static bool operator !=(BFloat16 left, BFloat16 right) => (float)left != (float)right;
+
+ ///
+ public static bool operator <(BFloat16 left, BFloat16 right) => (float)left < (float)right;
+
+ ///
+ public static bool operator >(BFloat16 left, BFloat16 right) => (float)left > (float)right;
+
+ ///
+ public static bool operator <=(BFloat16 left, BFloat16 right) => (float)left <= (float)right;
+
+ ///
+ public static bool operator >=(BFloat16 left, BFloat16 right) => (float)left >= (float)right;
+
+ // Equality
+
+ ///
+ /// Returns a value that indicates whether this instance is equal to a specified value.
+ ///
+ public bool Equals(BFloat16 other) => ((float)this).Equals((float)other);
+
+ ///
+ /// Returns a value that indicates whether this instance is equal to a specified .
+ ///
+ public override bool Equals(object? obj) => obj is BFloat16 other && Equals(other);
+
+ ///
+ /// Serves as the default hash function.
+ ///
+ public override int GetHashCode() => ((float)this).GetHashCode();
+
+ ///
+ /// Returns a string representation of the current value.
+ ///
+ public override string ToString() => Number.FormatFloat(this, null, NumberFormatInfo.CurrentInfo);
+
+ ///
+ /// Returns a string representation of the current value using the specified .
+ ///
+ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format)
+ {
+ return Number.FormatFloat(this, format, NumberFormatInfo.CurrentInfo);
+ }
+
+ ///
+ /// Returns a string representation of the current value with the specified .
+ ///
+ public string ToString(IFormatProvider? provider)
+ {
+ return Number.FormatFloat(this, null, NumberFormatInfo.GetInstance(provider));
+ }
+
+ ///
+ /// Returns a string representation of the current value using the specified and .
+ ///
+ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, IFormatProvider? provider)
+ {
+ return Number.FormatFloat(this, format, NumberFormatInfo.GetInstance(provider));
+ }
+
+ ///
+ /// Tries to format the value of the current BFloat16 instance into the provided span of characters.
+ ///
+ /// When this method returns, this instance's value formatted as a span of characters.
+ /// When this method returns, the number of characters that were written in .
+ /// A span containing the characters that represent a standard or custom format string that defines the acceptable format for .
+ /// An optional object that supplies culture-specific formatting information for .
+ ///
+ public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null)
+ {
+ return Number.TryFormatFloat(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+ }
+
+ ///
+ public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null)
+ {
+ return Number.TryFormatFloat(this, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten);
+ }
+
+ //
+ // Explicit Convert To BFloat16
+ //
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(char value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(decimal value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(double value)
+ {
+ // See explaination of the algorithm at Half.operator Half(float)
+
+ // Minimum exponent for rounding
+ const ulong MinExp = 0x3810_0000_0000_0000u;
+ // Exponent displacement #1
+ const ulong Exponent942 = 0x3ae0_0000_0000_0000u;
+ // Exponent mask
+ const ulong SingleBiasedExponentMask = double.BiasedExponentMask;
+ // Exponent displacement #2
+ const ulong Exponent45 = 0x02D0_0000_0000_0000u;
+ // The value above BFloat16.MaxValue
+ const double BFloat16AboveMaxValue = 3.39617752923046E+38;
+ // Mask for exponent bits in BFloat16
+ const ulong ExponentMask = BiasedExponentMask;
+ ulong bitValue = BitConverter.DoubleToUInt64Bits(value);
+ // Extract sign bit
+ ulong sign = (bitValue & double.SignMask) >> 48;
+ // Detecting NaN (~0u if a is not NaN)
+ ulong realMask = (ulong)(Unsafe.BitCast(double.IsNaN(value)) - 1);
+ // Clear sign bit
+ value = double.Abs(value);
+ // Rectify values that are Infinity in BFloat16. (float.Min now emits vminps instruction if one of two arguments is a constant)
+ value = double.Min(BFloat16AboveMaxValue, value);
+ // Rectify lower exponent
+ ulong exponentOffset0 = BitConverter.DoubleToUInt64Bits(double.Max(value, BitConverter.UInt64BitsToDouble(MinExp)));
+ // Extract exponent
+ exponentOffset0 &= SingleBiasedExponentMask;
+ // Add exponent by 45
+ exponentOffset0 += Exponent45;
+ // Round Single into BFloat16's precision (NaN also gets modified here, just setting the MSB of fraction)
+ value += BitConverter.UInt64BitsToDouble(exponentOffset0);
+ bitValue = BitConverter.DoubleToUInt64Bits(value);
+ // Only exponent bits will be modified if NaN
+ ulong maskedBFloat16ExponentForNaN = ~realMask & ExponentMask;
+ // Subtract exponent by 942
+ bitValue -= Exponent942;
+ // Shift bitValue right by 45 bits to match the boundary of exponent part and fraction part.
+ ulong newExponent = bitValue >> 45;
+ // Clear the fraction parts if the value was NaN.
+ bitValue &= realMask;
+ // Merge the exponent part with fraction part, and add the exponent part and fraction part's overflow.
+ bitValue += newExponent;
+ // Clear exponents if value is NaN
+ bitValue &= ~maskedBFloat16ExponentForNaN;
+ // Merge sign bit with possible NaN exponent
+ ulong signAndMaskedExponent = maskedBFloat16ExponentForNaN | sign;
+ // Merge sign bit and possible NaN exponent
+ bitValue |= signAndMaskedExponent;
+ // The final result
+ return new BFloat16((ushort)bitValue);
+ }
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(short value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(Half value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(int value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(long value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(Int128 value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(nint value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator BFloat16(float value)
+ {
+ uint bits = BitConverter.SingleToUInt32Bits(value);
+ uint upper = bits >> 16;
+ // Only do rounding for finite numbers
+ if (float.IsFinite(value))
+ {
+ uint lower = (ushort)bits;
+ // Determine the increment for rounding
+ // When upper is even, midpoint (0x8000) will tie to no increment, which is effectively a decrement of lower
+ uint lowerShift = (~upper) & (lower >> 15) & 1; // Upper is even & lower>=0x8000 (not 0)
+ lower -= lowerShift;
+ uint increment = lower >> 15;
+ // Do the increment, MaxValue will be correctly increased to Infinity
+ upper += increment;
+ }
+ return new BFloat16((ushort)upper);
+ }
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator BFloat16(ushort value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator BFloat16(uint value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator BFloat16(ulong value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator BFloat16(nuint value) => (BFloat16)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator BFloat16(UInt128 value) => (BFloat16)(float)value;
+
+ //
+ // Explicit Convert From BFloat16
+ //
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator byte(BFloat16 value) => (byte)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked byte(BFloat16 value) => checked((byte)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator char(BFloat16 value) => (char)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked char(BFloat16 value) => checked((char)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator decimal(BFloat16 value) => (decimal)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator short(BFloat16 value) => (short)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked short(BFloat16 value) => checked((short)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator int(BFloat16 value) => (int)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked int(BFloat16 value) => checked((int)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator long(BFloat16 value) => (long)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked long(BFloat16 value) => checked((long)(float)value);
+
+ /// Explicitly converts a value to its nearest representable .
+ /// The value to convert.
+ /// converted to a 128-bit signed integer.
+ public static explicit operator Int128(BFloat16 value) => (Int128)(double)(value);
+
+ /// Explicitly converts a value to its nearest representable , throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to a 128-bit signed integer.
+ /// is not representable by .
+ public static explicit operator checked Int128(BFloat16 value) => checked((Int128)(double)(value));
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator nint(BFloat16 value) => (nint)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ public static explicit operator checked nint(BFloat16 value) => checked((nint)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator sbyte(BFloat16 value) => (sbyte)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked sbyte(BFloat16 value) => checked((sbyte)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator ushort(BFloat16 value) => (ushort)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked ushort(BFloat16 value) => checked((ushort)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator uint(BFloat16 value) => (uint)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked uint(BFloat16 value) => checked((uint)(float)value);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator ulong(BFloat16 value) => (ulong)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked ulong(BFloat16 value) => checked((ulong)(float)value);
+
+ /// Explicitly converts a value to its nearest representable .
+ /// The value to convert.
+ /// converted to a 128-bit unsigned integer.
+ [CLSCompliant(false)]
+ public static explicit operator UInt128(BFloat16 value) => (UInt128)(double)(value);
+
+ /// Explicitly converts a value to its nearest representable , throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to a 128-bit unsigned integer.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked UInt128(BFloat16 value) => checked((UInt128)(double)(value));
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static explicit operator nuint(BFloat16 value) => (nuint)(float)value;
+
+ /// Explicitly converts a value to its nearest representable value, throwing an overflow exception for any values that fall outside the representable range.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ /// is not representable by .
+ [CLSCompliant(false)]
+ public static explicit operator checked nuint(BFloat16 value) => checked((nuint)(float)value);
+
+ //
+ // Implicit Convert To BFloat16
+ //
+
+ /// Implicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static implicit operator BFloat16(byte value) => (BFloat16)(float)value;
+
+ /// Implicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ [CLSCompliant(false)]
+ public static implicit operator BFloat16(sbyte value) => (BFloat16)(float)value;
+
+ //
+ // Implicit Convert From Half (actually explicit)
+ //
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+
+ public static explicit operator float(BFloat16 value) => BitConverter.Int32BitsToSingle(value._value << 16);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator double(BFloat16 value) => (double)(float)value;
+
+ //
+ // IAdditionOperators
+ //
+
+ ///
+ public static BFloat16 operator +(BFloat16 left, BFloat16 right) => (BFloat16)((float)left + (float)right);
+
+ //
+ // IAdditiveIdentity
+ //
+
+ ///
+ static BFloat16 IAdditiveIdentity.AdditiveIdentity => new BFloat16(PositiveZeroBits);
+
+ //
+ // IBinaryNumber
+ //
+
+ ///
+ static BFloat16 IBinaryNumber.AllBitsSet => new BFloat16(0xFFFF);
+
+ ///
+ public static bool IsPow2(BFloat16 value)
+ {
+ ushort bits = value._value;
+
+ if ((short)bits <= 0)
+ {
+ // Zero and negative values cannot be powers of 2
+ return false;
+ }
+
+ byte biasedExponent = ExtractBiasedExponentFromBits(bits);
+ ushort trailingSignificand = ExtractTrailingSignificandFromBits(bits);
+
+ if (biasedExponent == MinBiasedExponent)
+ {
+ // Subnormal values have 1 bit set when they're powers of 2
+ return ushort.PopCount(trailingSignificand) == 1;
+ }
+ else if (biasedExponent == MaxBiasedExponent)
+ {
+ // NaN and Infinite values cannot be powers of 2
+ return false;
+ }
+
+ // Normal values have 0 bits set when they're powers of 2
+ return trailingSignificand == MinTrailingSignificand;
+ }
+
+ ///
+ public static BFloat16 Log2(BFloat16 value) => (BFloat16)MathF.Log2((float)value);
+
+ //
+ // IBitwiseOperators
+ //
+
+ ///
+ static BFloat16 IBitwiseOperators.operator &(BFloat16 left, BFloat16 right)
+ {
+ return new BFloat16((ushort)(left._value & right._value));
+ }
+
+ ///
+ static BFloat16 IBitwiseOperators.operator |(BFloat16 left, BFloat16 right)
+ {
+ return new BFloat16((ushort)(left._value | right._value));
+ }
+
+ ///
+ static BFloat16 IBitwiseOperators.operator ^(BFloat16 left, BFloat16 right)
+ {
+ return new BFloat16((ushort)(left._value ^ right._value));
+ }
+
+ ///
+ static BFloat16 IBitwiseOperators.operator ~(BFloat16 value)
+ {
+ return new BFloat16((ushort)(~value._value));
+ }
+
+ //
+ // IDecrementOperators
+ //
+
+ ///
+ public static BFloat16 operator --(BFloat16 value)
+ {
+ var tmp = (float)value;
+ --tmp;
+ return (BFloat16)tmp;
+ }
+
+ //
+ // IDivisionOperators
+ //
+
+ ///
+ public static BFloat16 operator /(BFloat16 left, BFloat16 right) => (BFloat16)((float)left / (float)right);
+
+ //
+ // IExponentialFunctions
+ //
+
+ ///
+ public static BFloat16 Exp(BFloat16 x) => (BFloat16)MathF.Exp((float)x);
+
+ ///
+ public static BFloat16 ExpM1(BFloat16 x) => (BFloat16)float.ExpM1((float)x);
+
+ ///
+ public static BFloat16 Exp2(BFloat16 x) => (BFloat16)float.Exp2((float)x);
+
+ ///
+ public static BFloat16 Exp2M1(BFloat16 x) => (BFloat16)float.Exp2M1((float)x);
+
+ ///
+ public static BFloat16 Exp10(BFloat16 x) => (BFloat16)float.Exp10((float)x);
+
+ ///
+ public static BFloat16 Exp10M1(BFloat16 x) => (BFloat16)float.Exp10M1((float)x);
+
+ //
+ // IFloatingPoint
+ //
+
+ ///
+ public static BFloat16 Ceiling(BFloat16 x) => (BFloat16)MathF.Ceiling((float)x);
+
+ ///
+ public static BFloat16 Floor(BFloat16 x) => (BFloat16)MathF.Floor((float)x);
+
+ ///
+ public static BFloat16 Round(BFloat16 x) => (BFloat16)MathF.Round((float)x);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, int digits) => (BFloat16)MathF.Round((float)x, digits);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, MidpointRounding mode) => (BFloat16)MathF.Round((float)x, mode);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, int digits, MidpointRounding mode) => (BFloat16)MathF.Round((float)x, digits, mode);
+
+ ///
+ public static BFloat16 Truncate(BFloat16 x) => (BFloat16)MathF.Truncate((float)x);
+
+ ///
+ int IFloatingPoint.GetExponentByteCount() => sizeof(sbyte);
+
+ ///
+ int IFloatingPoint.GetExponentShortestBitLength()
+ {
+ sbyte exponent = Exponent;
+
+ if (exponent >= 0)
+ {
+ return (sizeof(sbyte) * 8) - sbyte.LeadingZeroCount(exponent);
+ }
+ else
+ {
+ return (sizeof(sbyte) * 8) + 1 - sbyte.LeadingZeroCount((sbyte)(~exponent));
+ }
+ }
+
+ ///
+ int IFloatingPoint.GetSignificandByteCount() => sizeof(ushort);
+
+ ///
+ int IFloatingPoint.GetSignificandBitLength() => SignificandLength;
+
+ ///
+ bool IFloatingPoint.TryWriteExponentBigEndian(Span destination, out int bytesWritten)
+ {
+ if (destination.Length >= sizeof(sbyte))
+ {
+ destination[0] = (byte)Exponent;
+ bytesWritten = sizeof(sbyte);
+ return true;
+ }
+
+ bytesWritten = 0;
+ return false;
+ }
+
+ ///
+ bool IFloatingPoint.TryWriteExponentLittleEndian(Span destination, out int bytesWritten)
+ {
+ if (destination.Length >= sizeof(sbyte))
+ {
+ destination[0] = (byte)Exponent;
+ bytesWritten = sizeof(sbyte);
+ return true;
+ }
+
+ bytesWritten = 0;
+ return false;
+ }
+
+ ///
+ bool IFloatingPoint.TryWriteSignificandBigEndian(Span destination, out int bytesWritten)
+ {
+ if (BinaryPrimitives.TryWriteUInt16BigEndian(destination, Significand))
+ {
+ bytesWritten = sizeof(uint);
+ return true;
+ }
+
+ bytesWritten = 0;
+ return false;
+ }
+
+ ///
+ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destination, out int bytesWritten)
+ {
+ if (BinaryPrimitives.TryWriteUInt16LittleEndian(destination, Significand))
+ {
+ bytesWritten = sizeof(uint);
+ return true;
+ }
+
+ bytesWritten = 0;
+ return false;
+ }
+
+ //
+ // IFloatingPointConstants
+ //
+
+ ///
+ public static BFloat16 E => new BFloat16(EBits);
+
+ ///
+ public static BFloat16 Pi => new BFloat16(PiBits);
+
+ ///
+ public static BFloat16 Tau => new BFloat16(TauBits);
+
+ //
+ // IFloatingPointIeee754
+ //
+
+ ///
+ public static BFloat16 NegativeZero => new BFloat16(NegativeZeroBits);
+
+ ///
+ public static BFloat16 Atan2(BFloat16 y, BFloat16 x) => (BFloat16)MathF.Atan2((float)y, (float)x);
+
+ ///
+ public static BFloat16 Atan2Pi(BFloat16 y, BFloat16 x) => (BFloat16)float.Atan2Pi((float)y, (float)x);
+
+ ///
+ public static BFloat16 BitDecrement(BFloat16 x)
+ {
+ uint bits = x._value;
+
+ if (!IsFinite(x))
+ {
+ // NaN returns NaN
+ // -Infinity returns -Infinity
+ // +Infinity returns MaxValue
+ return (bits == PositiveInfinityBits) ? MaxValue : x;
+ }
+
+ if (bits == PositiveZeroBits)
+ {
+ // +0.0 returns -Epsilon
+ return -Epsilon;
+ }
+
+ // Negative values need to be incremented
+ // Positive values need to be decremented
+
+ if (IsNegative(x))
+ {
+ bits += 1;
+ }
+ else
+ {
+ bits -= 1;
+ }
+ return new BFloat16((ushort)bits);
+ }
+
+ ///
+ public static BFloat16 BitIncrement(BFloat16 x)
+ {
+ uint bits = x._value;
+
+ if (!IsFinite(x))
+ {
+ // NaN returns NaN
+ // -Infinity returns MinValue
+ // +Infinity returns +Infinity
+ return (bits == NegativeInfinityBits) ? MinValue : x;
+ }
+
+ if (bits == NegativeZeroBits)
+ {
+ // -0.0 returns Epsilon
+ return Epsilon;
+ }
+
+ // Negative values need to be decremented
+ // Positive values need to be incremented
+
+ if (IsNegative(x))
+ {
+ bits -= 1;
+ }
+ else
+ {
+ bits += 1;
+ }
+ return new BFloat16((ushort)bits);
+ }
+
+ ///
+ public static BFloat16 FusedMultiplyAdd(BFloat16 left, BFloat16 right, BFloat16 addend) => (BFloat16)MathF.FusedMultiplyAdd((float)left, (float)right, (float)addend);
+
+ ///
+ public static BFloat16 Ieee754Remainder(BFloat16 left, BFloat16 right) => (BFloat16)MathF.IEEERemainder((float)left, (float)right);
+
+ ///
+ public static int ILogB(BFloat16 x)
+ {
+ // This code is based on `ilogbf` from amd/aocl-libm-ose
+ // Copyright (C) 2008-2022 Advanced Micro Devices, Inc. All rights reserved.
+ //
+ // Licensed under the BSD 3-Clause "New" or "Revised" License
+ // See THIRD-PARTY-NOTICES.TXT for the full license text
+
+ if (!IsNormal(x)) // x is zero, subnormal, infinity, or NaN
+ {
+ if (IsZero(x))
+ {
+ return int.MinValue;
+ }
+
+ if (!IsFinite(x)) // infinity or NaN
+ {
+ return int.MaxValue;
+ }
+
+ Debug.Assert(IsSubnormal(x));
+ return MinExponent - (BitOperations.TrailingZeroCount(x.TrailingSignificand) - BiasedExponentLength);
+ }
+
+ return x.Exponent;
+ }
+
+ ///
+ public static BFloat16 Lerp(BFloat16 value1, BFloat16 value2, BFloat16 amount) => (BFloat16)float.Lerp((float)value1, (float)value2, (float)amount);
+
+ ///
+ public static BFloat16 ReciprocalEstimate(BFloat16 x) => (BFloat16)MathF.ReciprocalEstimate((float)x);
+
+ ///
+ public static BFloat16 ReciprocalSqrtEstimate(BFloat16 x) => (BFloat16)MathF.ReciprocalSqrtEstimate((float)x);
+
+ ///
+ public static BFloat16 ScaleB(BFloat16 x, int n) => (BFloat16)MathF.ScaleB((float)x, n);
+
+ // ///
+ // public static BFloat16 Compound(BFloat16 x, BFloat16 n) => (BFloat16)MathF.Compound((float)x, (float)n);
+
+ //
+ // IHyperbolicFunctions
+ //
+
+ ///
+ public static BFloat16 Acosh(BFloat16 x) => (BFloat16)MathF.Acosh((float)x);
+
+ ///
+ public static BFloat16 Asinh(BFloat16 x) => (BFloat16)MathF.Asinh((float)x);
+
+ ///
+ public static BFloat16 Atanh(BFloat16 x) => (BFloat16)MathF.Atanh((float)x);
+
+ ///
+ public static BFloat16 Cosh(BFloat16 x) => (BFloat16)MathF.Cosh((float)x);
+
+ ///
+ public static BFloat16 Sinh(BFloat16 x) => (BFloat16)MathF.Sinh((float)x);
+
+ ///
+ public static BFloat16 Tanh(BFloat16 x) => (BFloat16)MathF.Tanh((float)x);
+
+ //
+ // IIncrementOperators
+ //
+
+ ///
+ public static BFloat16 operator ++(BFloat16 value)
+ {
+ var tmp = (float)value;
+ ++tmp;
+ return (BFloat16)tmp;
+ }
+
+ //
+ // ILogarithmicFunctions
+ //
+
+ ///
+ public static BFloat16 Log(BFloat16 x) => (BFloat16)MathF.Log((float)x);
+
+ ///
+ public static BFloat16 Log(BFloat16 x, BFloat16 newBase) => (BFloat16)MathF.Log((float)x, (float)newBase);
+
+ ///
+ public static BFloat16 Log10(BFloat16 x) => (BFloat16)MathF.Log10((float)x);
+
+ ///
+ public static BFloat16 LogP1(BFloat16 x) => (BFloat16)float.LogP1((float)x);
+
+ ///
+ public static BFloat16 Log2P1(BFloat16 x) => (BFloat16)float.Log2P1((float)x);
+
+ ///
+ public static BFloat16 Log10P1(BFloat16 x) => (BFloat16)float.Log10P1((float)x);
+
+ //
+ // IModulusOperators
+ //
+
+ ///
+ public static BFloat16 operator %(BFloat16 left, BFloat16 right) => (BFloat16)((float)left % (float)right);
+
+ //
+ // IMultiplicativeIdentity
+ //
+
+ ///
+ public static BFloat16 MultiplicativeIdentity => new BFloat16(PositiveOneBits);
+
+ //
+ // IMultiplyOperators
+ //
+
+ ///
+ public static BFloat16 operator *(BFloat16 left, BFloat16 right) => (BFloat16)((float)left * (float)right);
+
+ //
+ // INumber
+ //
+
+ ///
+ public static BFloat16 Clamp(BFloat16 value, BFloat16 min, BFloat16 max) => (BFloat16)Math.Clamp((float)value, (float)min, (float)max);
+
+ ///
+ public static BFloat16 CopySign(BFloat16 value, BFloat16 sign)
+ {
+ // This method is required to work for all inputs,
+ // including NaN, so we operate on the raw bits.
+ uint xbits = value._value;
+ uint ybits = sign._value;
+
+ // Remove the sign from x, and remove everything but the sign from y
+ // Then, simply OR them to get the correct sign
+ return new BFloat16((ushort)((xbits & ~SignMask) | (ybits & SignMask)));
+ }
+
+ ///
+ public static BFloat16 Max(BFloat16 x, BFloat16 y) => (BFloat16)MathF.Max((float)x, (float)y);
+
+ ///
+ public static BFloat16 MaxNumber(BFloat16 x, BFloat16 y)
+ {
+ // This matches the IEEE 754:2019 `maximumNumber` function
+ //
+ // It does not propagate NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
+
+ if (x != y)
+ {
+ if (!IsNaN(y))
+ {
+ return y < x ? x : y;
+ }
+
+ return x;
+ }
+
+ return IsNegative(y) ? x : y;
+ }
+
+ ///
+ public static BFloat16 Min(BFloat16 x, BFloat16 y) => (BFloat16)MathF.Min((float)x, (float)y);
+
+ ///
+ public static BFloat16 MinNumber(BFloat16 x, BFloat16 y)
+ {
+ // This matches the IEEE 754:2019 `minimumNumber` function
+ //
+ // It does not propagate NaN inputs back to the caller and
+ // otherwise returns the larger of the inputs. It
+ // treats +0 as larger than -0 as per the specification.
+
+ if (x != y)
+ {
+ if (!IsNaN(y))
+ {
+ return x < y ? x : y;
+ }
+
+ return x;
+ }
+
+ return IsNegative(x) ? x : y;
+ }
+
+ ///
+ public static int Sign(BFloat16 value)
+ {
+ if (IsNaN(value))
+ {
+ throw new ArithmeticException(SR.Arithmetic_NaN);
+ }
+
+ if (IsZero(value))
+ {
+ return 0;
+ }
+ else if (IsNegative(value))
+ {
+ return -1;
+ }
+
+ return +1;
+ }
+
+ //
+ // INumberBase
+ //
+
+ ///
+ public static BFloat16 One => new BFloat16(PositiveOneBits);
+
+ ///
+ static int INumberBase.Radix => 2;
+
+ ///
+ public static BFloat16 Zero => new BFloat16(PositiveZeroBits);
+
+ ///
+ public static BFloat16 Abs(BFloat16 value) => new BFloat16((ushort)(value._value & ~SignMask));
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static BFloat16 CreateChecked(TOther value)
+ where TOther : INumberBase
+ {
+ BFloat16 result;
+
+ if (typeof(TOther) == typeof(BFloat16))
+ {
+ result = (BFloat16)(object)value;
+ }
+ else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToChecked(value, out result))
+ {
+ ThrowHelper.ThrowNotSupportedException();
+ }
+
+ return result;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static BFloat16 CreateSaturating(TOther value)
+ where TOther : INumberBase
+ {
+ BFloat16 result;
+
+ if (typeof(TOther) == typeof(BFloat16))
+ {
+ result = (BFloat16)(object)value;
+ }
+ else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToSaturating(value, out result))
+ {
+ ThrowHelper.ThrowNotSupportedException();
+ }
+
+ return result;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static BFloat16 CreateTruncating(TOther value)
+ where TOther : INumberBase
+ {
+ BFloat16 result;
+
+ if (typeof(TOther) == typeof(BFloat16))
+ {
+ result = (BFloat16)(object)value;
+ }
+ else if (!TryConvertFrom(value, out result) && !TOther.TryConvertToTruncating(value, out result))
+ {
+ ThrowHelper.ThrowNotSupportedException();
+ }
+
+ return result;
+ }
+
+ ///
+ static bool INumberBase.IsCanonical(BFloat16 value) => true;
+
+ ///
+ static bool INumberBase.IsComplexNumber(BFloat16 value) => false;
+
+ ///
+ public static bool IsEvenInteger(BFloat16 value) => float.IsEvenInteger((float)value);
+
+ ///
+ static bool INumberBase.IsImaginaryNumber(BFloat16 value) => false;
+
+ ///
+ public static bool IsInteger(BFloat16 value) => float.IsInteger((float)value);
+
+ ///
+ public static bool IsOddInteger(BFloat16 value) => float.IsOddInteger((float)value);
+
+ ///
+ public static bool IsPositive(BFloat16 value) => (short)(value._value) >= 0;
+
+ ///
+ public static bool IsRealNumber(BFloat16 value)
+ {
+ // A NaN will never equal itself so this is an
+ // easy and efficient way to check for a real number.
+
+#pragma warning disable CS1718
+ return value == value;
+#pragma warning restore CS1718
+ }
+
+ ///
+ static bool INumberBase.IsZero(BFloat16 value) => IsZero(value);
+
+ ///
+ public static BFloat16 MaxMagnitude(BFloat16 x, BFloat16 y) => (BFloat16)MathF.MaxMagnitude((float)x, (float)y);
+
+ ///
+ public static BFloat16 MaxMagnitudeNumber(BFloat16 x, BFloat16 y)
+ {
+ // This matches the IEEE 754:2019 `maximumMagnitudeNumber` function
+ //
+ // It does not propagate NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
+
+ BFloat16 ax = Abs(x);
+ BFloat16 ay = Abs(y);
+
+ if ((ax > ay) || IsNaN(ay))
+ {
+ return x;
+ }
+
+ if (ax == ay)
+ {
+ return IsNegative(x) ? y : x;
+ }
+
+ return y;
+ }
+
+ ///
+ public static BFloat16 MinMagnitude(BFloat16 x, BFloat16 y) => (BFloat16)MathF.MinMagnitude((float)x, (float)y);
+
+ ///
+ public static BFloat16 MinMagnitudeNumber(BFloat16 x, BFloat16 y)
+ {
+ // This matches the IEEE 754:2019 `minimumMagnitudeNumber` function
+ //
+ // It does not propagate NaN inputs back to the caller and
+ // otherwise returns the input with a larger magnitude.
+ // It treats +0 as larger than -0 as per the specification.
+
+ BFloat16 ax = Abs(x);
+ BFloat16 ay = Abs(y);
+
+ if ((ax < ay) || IsNaN(ay))
+ {
+ return x;
+ }
+
+ if (ax == ay)
+ {
+ return IsNegative(x) ? x : y;
+ }
+
+ return y;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertFromChecked(TOther value, out BFloat16 result)
+ {
+ return TryConvertFrom(value, out result);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertFromSaturating(TOther value, out BFloat16 result)
+ {
+ return TryConvertFrom(value, out result);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertFromTruncating(TOther value, out BFloat16 result)
+ {
+ return TryConvertFrom(value, out result);
+ }
+
+ private static bool TryConvertFrom(TOther value, out BFloat16 result)
+ where TOther : INumberBase
+ {
+ // In order to reduce overall code duplication and improve the inlinabilty of these
+ // methods for the corelib types we have `ConvertFrom` handle the same sign and
+ // `ConvertTo` handle the opposite sign. However, since there is an uneven split
+ // between signed and unsigned types, the one that handles unsigned will also
+ // handle `Decimal`.
+ //
+ // That is, `ConvertFrom` for `BFloat16` will handle the other signed types and
+ // `ConvertTo` will handle the unsigned types
+
+ if (typeof(TOther) == typeof(double))
+ {
+ double actualValue = (double)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(short))
+ {
+ short actualValue = (short)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(int))
+ {
+ int actualValue = (int)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(long))
+ {
+ long actualValue = (long)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Int128))
+ {
+ Int128 actualValue = (Int128)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nint))
+ {
+ nint actualValue = (nint)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(sbyte))
+ {
+ sbyte actualValue = (sbyte)(object)value;
+ result = actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(float))
+ {
+ float actualValue = (float)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Half))
+ {
+ Half actualValue = (Half)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else
+ {
+ result = default;
+ return false;
+ }
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertToChecked(BFloat16 value, [MaybeNullWhen(false)] out TOther result)
+ {
+ // `BFloat16` is non-first class type in System.Numerics namespace.
+ // It should handle all conversions from/to types under System namespace.
+
+ if (typeof(TOther) == typeof(sbyte))
+ {
+ sbyte actualResult = checked((sbyte)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(short))
+ {
+ short actualResult = checked((short)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(int))
+ {
+ int actualResult = checked((int)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(long))
+ {
+ long actualResult = checked((long)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Int128))
+ {
+ Int128 actualResult = checked((Int128)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nint))
+ {
+ nint actualResult = checked((nint)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ if (typeof(TOther) == typeof(byte))
+ {
+ byte actualResult = checked((byte)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(char))
+ {
+ char actualResult = checked((char)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(decimal))
+ {
+ decimal actualResult = checked((decimal)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ushort))
+ {
+ ushort actualResult = checked((ushort)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(uint))
+ {
+ uint actualResult = checked((uint)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ulong))
+ {
+ ulong actualResult = checked((ulong)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(UInt128))
+ {
+ UInt128 actualResult = checked((UInt128)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nuint))
+ {
+ nuint actualResult = checked((nuint)value);
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else
+ {
+ result = default;
+ return false;
+ }
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertToSaturating(BFloat16 value, [MaybeNullWhen(false)] out TOther result)
+ {
+ return TryConvertTo(value, out result);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static bool INumberBase.TryConvertToTruncating(BFloat16 value, [MaybeNullWhen(false)] out TOther result)
+ {
+ return TryConvertTo(value, out result);
+ }
+
+ private static bool TryConvertTo(BFloat16 value, [MaybeNullWhen(false)] out TOther result)
+ where TOther : INumberBase
+ {
+ // `BFloat16` is non-first class type in System.Numerics namespace.
+ // It should handle all conversions from/to types under System namespace.
+
+ if (typeof(TOther) == typeof(sbyte))
+ {
+ sbyte actualResult = (value >= sbyte.MaxValue) ? sbyte.MaxValue :
+ (value <= sbyte.MinValue) ? sbyte.MinValue : (sbyte)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(short))
+ {
+ short actualResult = ((float)value >= short.MaxValue) ? short.MaxValue :
+ ((float)value <= short.MinValue) ? short.MinValue : (short)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(int))
+ {
+ int actualResult = ((float)value >= int.MaxValue) ? int.MaxValue :
+ ((float)value <= int.MinValue) ? int.MinValue : (int)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(long))
+ {
+ long actualResult = ((float)value >= long.MaxValue) ? long.MaxValue :
+ ((float)value <= long.MinValue) ? long.MinValue : (long)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Int128))
+ {
+ Int128 actualResult = ((float)value >= +170141183460469231731687303715884105727.0f) ? Int128.MaxValue :
+ ((float)value <= -170141183460469231731687303715884105728.0f) ? Int128.MinValue : (Int128)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nint))
+ {
+ nint actualResult = ((float)value >= nint.MaxValue) ? nint.MaxValue :
+ ((float)value <= nint.MinValue) ? nint.MinValue : (nint)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(byte))
+ {
+ byte actualResult = ((float)value >= byte.MaxValue) ? byte.MaxValue :
+ ((float)value <= byte.MinValue) ? byte.MinValue : (byte)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(char))
+ {
+ char actualResult = ((float)value >= char.MaxValue) ? char.MaxValue :
+ (value <= Zero) ? char.MinValue : (char)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(decimal))
+ {
+ decimal actualResult = ((float)value >= +79228162514264337593543950336.0f) ? decimal.MaxValue :
+ ((float)value <= -79228162514264337593543950336.0f) ? decimal.MinValue :
+ IsNaN(value) ? 0.0m : (decimal)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ushort))
+ {
+ ushort actualResult = ((float)value >= ushort.MaxValue) ? ushort.MaxValue :
+ (value <= Zero) ? ushort.MinValue : (ushort)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(uint))
+ {
+ uint actualResult = ((float)value >= uint.MaxValue) ? uint.MaxValue :
+ (value <= Zero) ? uint.MinValue : (uint)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ulong))
+ {
+ ulong actualResult = ((float)value >= ulong.MaxValue) ? ulong.MaxValue :
+ (value <= Zero) ? ulong.MinValue : (ulong)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(UInt128))
+ {
+ UInt128 actualResult = (value == PositiveInfinity) ? UInt128.MaxValue :
+ (value <= Zero) ? UInt128.MinValue : (UInt128)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nuint))
+ {
+ nuint actualResult = ((float)value >= nuint.MaxValue) ? nuint.MaxValue :
+ (value <= Zero) ? nuint.MinValue : (nuint)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else
+ {
+ result = default;
+ return false;
+ }
+ }
+
+ //
+ // IParsable
+ //
+
+ ///
+ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out BFloat16 result) => TryParse(s, DefaultParseStyle, provider, out result);
+
+ //
+ // IPowerFunctions
+ //
+
+ ///
+ public static BFloat16 Pow(BFloat16 x, BFloat16 y) => (BFloat16)MathF.Pow((float)x, (float)y);
+
+ //
+ // IRootFunctions
+ //
+
+ ///
+ public static BFloat16 Cbrt(BFloat16 x) => (BFloat16)MathF.Cbrt((float)x);
+
+ ///
+ public static BFloat16 Hypot(BFloat16 x, BFloat16 y) => (BFloat16)float.Hypot((float)x, (float)y);
+
+ ///
+ public static BFloat16 RootN(BFloat16 x, int n) => (BFloat16)float.RootN((float)x, n);
+
+ ///
+ public static BFloat16 Sqrt(BFloat16 x) => (BFloat16)MathF.Sqrt((float)x);
+
+ //
+ // ISignedNumber
+ //
+
+ ///
+ public static BFloat16 NegativeOne => new BFloat16(NegativeOneBits);
+
+ //
+ // ISpanParsable
+ //
+
+ ///
+ public static BFloat16 Parse(ReadOnlySpan s, IFormatProvider? provider) => Parse(s, DefaultParseStyle, provider);
+
+ ///
+ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out BFloat16 result) => TryParse(s, DefaultParseStyle, provider, out result);
+
+ //
+ // ISubtractionOperators
+ //
+
+ ///
+ public static BFloat16 operator -(BFloat16 left, BFloat16 right) => (BFloat16)((float)left - (float)right);
+
+ //
+ // ITrigonometricFunctions
+ //
+
+ ///
+ public static BFloat16 Acos(BFloat16 x) => (BFloat16)MathF.Acos((float)x);
+
+ ///
+ public static BFloat16 AcosPi(BFloat16 x) => (BFloat16)float.AcosPi((float)x);
+
+ ///
+ public static BFloat16 Asin(BFloat16 x) => (BFloat16)MathF.Asin((float)x);
+
+ ///
+ public static BFloat16 AsinPi(BFloat16 x) => (BFloat16)float.AsinPi((float)x);
+
+ ///
+ public static BFloat16 Atan(BFloat16 x) => (BFloat16)MathF.Atan((float)x);
+
+ ///
+ public static BFloat16 AtanPi(BFloat16 x) => (BFloat16)float.AtanPi((float)x);
+
+ ///
+ public static BFloat16 Cos(BFloat16 x) => (BFloat16)MathF.Cos((float)x);
+
+ ///
+ public static BFloat16 CosPi(BFloat16 x) => (BFloat16)float.CosPi((float)x);
+
+ ///
+ public static BFloat16 DegreesToRadians(BFloat16 degrees)
+ {
+ // NOTE: Don't change the algorithm without consulting the DIM
+ // which elaborates on why this implementation was chosen
+
+ return (BFloat16)float.DegreesToRadians((float)degrees);
+ }
+
+ ///
+ public static BFloat16 RadiansToDegrees(BFloat16 radians)
+ {
+ // NOTE: Don't change the algorithm without consulting the DIM
+ // which elaborates on why this implementation was chosen
+
+ return (BFloat16)float.RadiansToDegrees((float)radians);
+ }
+
+ ///
+ public static BFloat16 Sin(BFloat16 x) => (BFloat16)MathF.Sin((float)x);
+
+ ///
+ public static (BFloat16 Sin, BFloat16 Cos) SinCos(BFloat16 x)
+ {
+ var (sin, cos) = MathF.SinCos((float)x);
+ return ((BFloat16)sin, (BFloat16)cos);
+ }
+
+ ///
+ public static (BFloat16 SinPi, BFloat16 CosPi) SinCosPi(BFloat16 x)
+ {
+ var (sinPi, cosPi) = float.SinCosPi((float)x);
+ return ((BFloat16)sinPi, (BFloat16)cosPi);
+ }
+
+ ///
+ public static BFloat16 SinPi(BFloat16 x) => (BFloat16)float.SinPi((float)x);
+
+ ///
+ public static BFloat16 Tan(BFloat16 x) => (BFloat16)MathF.Tan((float)x);
+
+ ///
+ public static BFloat16 TanPi(BFloat16 x) => (BFloat16)float.TanPi((float)x);
+
+ //
+ // IUnaryNegationOperators
+ //
+
+ ///
+ public static BFloat16 operator -(BFloat16 value) => (BFloat16)(-(float)value);
+
+ //
+ // IUnaryPlusOperators
+ //
+
+ ///
+ public static BFloat16 operator +(BFloat16 value) => value;
+
+ //
+ // IUtf8SpanParsable
+ //
+
+ ///
+ public static BFloat16 Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider? provider = null)
+ {
+ NumberFormatInfo.ValidateParseStyleInteger(style);
+ return Number.ParseFloat(utf8Text, style, NumberFormatInfo.GetInstance(provider));
+ }
+
+ ///
+ public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BFloat16 result)
+ {
+ NumberFormatInfo.ValidateParseStyleInteger(style);
+ return Number.TryParseFloat(utf8Text, style, NumberFormatInfo.GetInstance(provider), out result);
+ }
+
+ ///
+ public static BFloat16 Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => Parse(utf8Text, NumberStyles.Float | NumberStyles.AllowThousands, provider);
+
+ ///
+ public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BFloat16 result) => TryParse(utf8Text, NumberStyles.Float | NumberStyles.AllowThousands, provider, out result);
+
+ //
+ // IBinaryFloatParseAndFormatInfo
+ //
+
+ static int IBinaryFloatParseAndFormatInfo.NumberBufferLength => 96 + 1 + 1; // 96 for the longest input + 1 for rounding (+1 for the null terminator)
+
+ static ulong IBinaryFloatParseAndFormatInfo.ZeroBits => 0;
+ static ulong IBinaryFloatParseAndFormatInfo.InfinityBits => PositiveInfinityBits;
+
+ static ulong IBinaryFloatParseAndFormatInfo.NormalMantissaMask => (1UL << SignificandLength) - 1;
+ static ulong IBinaryFloatParseAndFormatInfo.DenormalMantissaMask => TrailingSignificandMask;
+
+ static int IBinaryFloatParseAndFormatInfo.MinBinaryExponent => 1 - MaxExponent;
+ static int IBinaryFloatParseAndFormatInfo.MaxBinaryExponent => MaxExponent;
+
+ static int IBinaryFloatParseAndFormatInfo.MinDecimalExponent => -41;
+ static int IBinaryFloatParseAndFormatInfo.MaxDecimalExponent => 39;
+
+ static int IBinaryFloatParseAndFormatInfo.ExponentBias => ExponentBias;
+ static ushort IBinaryFloatParseAndFormatInfo.ExponentBits => BiasedExponentLength;
+
+ static int IBinaryFloatParseAndFormatInfo.OverflowDecimalExponent => (MaxExponent + (2 * SignificandLength)) / 3;
+ static int IBinaryFloatParseAndFormatInfo.InfinityExponent => MaxBiasedExponent;
+
+ static ushort IBinaryFloatParseAndFormatInfo.NormalMantissaBits => SignificandLength;
+ static ushort IBinaryFloatParseAndFormatInfo.DenormalMantissaBits => TrailingSignificandLength;
+
+ static int IBinaryFloatParseAndFormatInfo.MinFastFloatDecimalExponent => -59;
+ static int IBinaryFloatParseAndFormatInfo.MaxFastFloatDecimalExponent => 38;
+
+ static int IBinaryFloatParseAndFormatInfo.MinExponentRoundToEven => -24;
+ static int IBinaryFloatParseAndFormatInfo.MaxExponentRoundToEven => 3;
+
+ static int IBinaryFloatParseAndFormatInfo.MaxExponentFastPath => 3;
+ static ulong IBinaryFloatParseAndFormatInfo.MaxMantissaFastPath => 2UL << TrailingSignificandLength;
+
+ static int IBinaryFloatParseAndFormatInfo.MaxRoundTripDigits => 4;
+
+ static int IBinaryFloatParseAndFormatInfo.MaxPrecisionCustomFormat => 4;
+
+ static BFloat16 IBinaryFloatParseAndFormatInfo.BitsToFloat(ulong bits) => new BFloat16((ushort)(bits));
+
+ static ulong IBinaryFloatParseAndFormatInfo.FloatToBits(BFloat16 value) => value._value;
+ }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs
index 28c545a65a628..130aa33f3298a 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Single.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs
@@ -2174,7 +2174,7 @@ public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFo
static ushort IBinaryFloatParseAndFormatInfo.NormalMantissaBits => SignificandLength;
static ushort IBinaryFloatParseAndFormatInfo.DenormalMantissaBits => TrailingSignificandLength;
- static int IBinaryFloatParseAndFormatInfo.MinFastFloatDecimalExponent => -65;
+ static int IBinaryFloatParseAndFormatInfo.MinFastFloatDecimalExponent => -64;
static int IBinaryFloatParseAndFormatInfo.MaxFastFloatDecimalExponent => 38;
static int IBinaryFloatParseAndFormatInfo.MinExponentRoundToEven => -17;
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index da44791d9607c..3e7bfe276fccb 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -11128,6 +11128,244 @@ public static void HtmlEncode(string? value, System.IO.TextWriter output) { }
}
namespace System.Numerics
{
+ public readonly partial struct BFloat16 : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.IUtf8SpanFormattable, System.IUtf8SpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IBinaryFloatingPointIeee754, System.Numerics.IBinaryNumber, System.Numerics.IBitwiseOperators, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IExponentialFunctions, System.Numerics.IFloatingPoint, System.Numerics.IFloatingPointConstants, System.Numerics.IFloatingPointIeee754, System.Numerics.IHyperbolicFunctions, System.Numerics.IIncrementOperators, System.Numerics.ILogarithmicFunctions, System.Numerics.IMinMaxValue, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IPowerFunctions, System.Numerics.IRootFunctions, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.ITrigonometricFunctions, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators
+ {
+ private readonly int _dummyPrimitive;
+ public static System.Numerics.BFloat16 E { get { throw null; } }
+ public static System.Numerics.BFloat16 Epsilon { get { throw null; } }
+ public static System.Numerics.BFloat16 MaxValue { get { throw null; } }
+ public static System.Numerics.BFloat16 MinValue { get { throw null; } }
+ public static System.Numerics.BFloat16 MultiplicativeIdentity { get { throw null; } }
+ public static System.Numerics.BFloat16 NaN { get { throw null; } }
+ public static System.Numerics.BFloat16 NegativeInfinity { get { throw null; } }
+ public static System.Numerics.BFloat16 NegativeOne { get { throw null; } }
+ public static System.Numerics.BFloat16 NegativeZero { get { throw null; } }
+ public static System.Numerics.BFloat16 One { get { throw null; } }
+ public static System.Numerics.BFloat16 Pi { get { throw null; } }
+ public static System.Numerics.BFloat16 PositiveInfinity { get { throw null; } }
+ static System.Numerics.BFloat16 System.Numerics.IAdditiveIdentity.AdditiveIdentity { get { throw null; } }
+ static System.Numerics.BFloat16 System.Numerics.IBinaryNumber.AllBitsSet { get { throw null; } }
+ static int System.Numerics.INumberBase.Radix { get { throw null; } }
+ public static System.Numerics.BFloat16 Tau { get { throw null; } }
+ public static System.Numerics.BFloat16 Zero { get { throw null; } }
+ public static System.Numerics.BFloat16 Abs(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 Acos(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Acosh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 AcosPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Asin(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Asinh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 AsinPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Atan(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Atan2(System.Numerics.BFloat16 y, System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Atan2Pi(System.Numerics.BFloat16 y, System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Atanh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 AtanPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 BitDecrement(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 BitIncrement(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Cbrt(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Ceiling(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Clamp(System.Numerics.BFloat16 value, System.Numerics.BFloat16 min, System.Numerics.BFloat16 max) { throw null; }
+ public int CompareTo(System.Numerics.BFloat16 other) { throw null; }
+ public int CompareTo(object? obj) { throw null; }
+ public static System.Numerics.BFloat16 CopySign(System.Numerics.BFloat16 value, System.Numerics.BFloat16 sign) { throw null; }
+ public static System.Numerics.BFloat16 Cos(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Cosh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 CosPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; }
+ public static System.Numerics.BFloat16 CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; }
+ public static System.Numerics.BFloat16 CreateTruncating(TOther value) where TOther : System.Numerics.INumberBase { throw null; }
+ public static System.Numerics.BFloat16 DegreesToRadians(System.Numerics.BFloat16 degrees) { throw null; }
+ public bool Equals(System.Numerics.BFloat16 other) { throw null; }
+ public override bool Equals(object? obj) { throw null; }
+ public static System.Numerics.BFloat16 Exp(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Exp10(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Exp10M1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Exp2(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Exp2M1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 ExpM1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Floor(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 FusedMultiplyAdd(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right, System.Numerics.BFloat16 addend) { throw null; }
+ public override int GetHashCode() { throw null; }
+ public static System.Numerics.BFloat16 Hypot(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 Ieee754Remainder(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static int ILogB(System.Numerics.BFloat16 x) { throw null; }
+ public static bool IsEvenInteger(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsFinite(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsInfinity(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsInteger(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsNaN(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsNegative(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsNegativeInfinity(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsNormal(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsOddInteger(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsPositive(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsPositiveInfinity(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsPow2(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsRealNumber(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsSubnormal(System.Numerics.BFloat16 value) { throw null; }
+ public static bool IsZero(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 Lerp(System.Numerics.BFloat16 value1, System.Numerics.BFloat16 value2, System.Numerics.BFloat16 amount) { throw null; }
+ public static System.Numerics.BFloat16 Log(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Log(System.Numerics.BFloat16 x, System.Numerics.BFloat16 newBase) { throw null; }
+ public static System.Numerics.BFloat16 Log10(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Log10P1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Log2(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 Log2P1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 LogP1(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Max(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MaxMagnitude(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MaxMagnitudeNumber(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MaxNumber(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 Min(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MinMagnitude(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MinMagnitudeNumber(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 MinNumber(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 operator +(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static explicit operator checked byte (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked char (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked short (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked int (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked long (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked System.Int128 (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator checked nint (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked sbyte (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked ushort (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked uint (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked ulong (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked System.UInt128 (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator checked nuint (System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 operator --(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 operator /(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static bool operator ==(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (char value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (decimal value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (double value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (System.Half value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (System.Int128 value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (short value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (int value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (long value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (nint value) { throw null; }
+ public static explicit operator byte (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator char (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator decimal (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator double (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator System.Int128 (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator short (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator int (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator long (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator nint (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator sbyte (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator float (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.UInt128 (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator ushort (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator uint (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator ulong (System.Numerics.BFloat16 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator nuint (System.Numerics.BFloat16 value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (float value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.Numerics.BFloat16 (System.UInt128 value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.Numerics.BFloat16 (ushort value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.Numerics.BFloat16 (uint value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.Numerics.BFloat16 (ulong value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static explicit operator System.Numerics.BFloat16 (nuint value) { throw null; }
+ public static bool operator >(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static bool operator >=(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static implicit operator System.Numerics.BFloat16 (byte value) { throw null; }
+ [System.CLSCompliantAttribute(false)]
+ public static implicit operator System.Numerics.BFloat16 (sbyte value) { throw null; }
+ public static System.Numerics.BFloat16 operator ++(System.Numerics.BFloat16 value) { throw null; }
+ public static bool operator !=(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static bool operator <(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static bool operator <=(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static System.Numerics.BFloat16 operator %(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static System.Numerics.BFloat16 operator *(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static System.Numerics.BFloat16 operator -(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ public static System.Numerics.BFloat16 operator -(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 operator +(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 Parse(System.ReadOnlySpan utf8Text, System.Globalization.NumberStyles style = System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowLeadingSign | System.Globalization.NumberStyles.AllowLeadingWhite | System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.AllowTrailingWhite, System.IFormatProvider? provider = null) { throw null; }
+ public static System.Numerics.BFloat16 Parse(System.ReadOnlySpan utf8Text, System.IFormatProvider? provider) { throw null; }
+ public static System.Numerics.BFloat16 Parse(System.ReadOnlySpan s, System.Globalization.NumberStyles style = System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowLeadingSign | System.Globalization.NumberStyles.AllowLeadingWhite | System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.AllowTrailingWhite, System.IFormatProvider? provider = null) { throw null; }
+ public static System.Numerics.BFloat16 Parse(System.ReadOnlySpan s, System.IFormatProvider? provider) { throw null; }
+ public static System.Numerics.BFloat16 Parse(string s) { throw null; }
+ public static System.Numerics.BFloat16 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
+ public static System.Numerics.BFloat16 Parse(string s, System.Globalization.NumberStyles style = System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowLeadingSign | System.Globalization.NumberStyles.AllowLeadingWhite | System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.AllowTrailingWhite, System.IFormatProvider? provider = null) { throw null; }
+ public static System.Numerics.BFloat16 Parse(string s, System.IFormatProvider? provider) { throw null; }
+ public static System.Numerics.BFloat16 Pow(System.Numerics.BFloat16 x, System.Numerics.BFloat16 y) { throw null; }
+ public static System.Numerics.BFloat16 RadiansToDegrees(System.Numerics.BFloat16 radians) { throw null; }
+ public static System.Numerics.BFloat16 ReciprocalEstimate(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 ReciprocalSqrtEstimate(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 RootN(System.Numerics.BFloat16 x, int n) { throw null; }
+ public static System.Numerics.BFloat16 Round(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Round(System.Numerics.BFloat16 x, int digits) { throw null; }
+ public static System.Numerics.BFloat16 Round(System.Numerics.BFloat16 x, int digits, System.MidpointRounding mode) { throw null; }
+ public static System.Numerics.BFloat16 Round(System.Numerics.BFloat16 x, System.MidpointRounding mode) { throw null; }
+ public static System.Numerics.BFloat16 ScaleB(System.Numerics.BFloat16 x, int n) { throw null; }
+ public static int Sign(System.Numerics.BFloat16 value) { throw null; }
+ public static System.Numerics.BFloat16 Sin(System.Numerics.BFloat16 x) { throw null; }
+ public static (System.Numerics.BFloat16 Sin, System.Numerics.BFloat16 Cos) SinCos(System.Numerics.BFloat16 x) { throw null; }
+ public static (System.Numerics.BFloat16 SinPi, System.Numerics.BFloat16 CosPi) SinCosPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Sinh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 SinPi(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Sqrt(System.Numerics.BFloat16 x) { throw null; }
+ static System.Numerics.BFloat16 System.Numerics.IBitwiseOperators.operator &(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ static System.Numerics.BFloat16 System.Numerics.IBitwiseOperators.operator |(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ static System.Numerics.BFloat16 System.Numerics.IBitwiseOperators.operator ^(System.Numerics.BFloat16 left, System.Numerics.BFloat16 right) { throw null; }
+ static System.Numerics.BFloat16 System.Numerics.IBitwiseOperators.operator ~(System.Numerics.BFloat16 value) { throw null; }
+ int System.Numerics.IFloatingPoint.GetExponentByteCount() { throw null; }
+ int System.Numerics.IFloatingPoint.GetExponentShortestBitLength() { throw null; }
+ int System.Numerics.IFloatingPoint.GetSignificandBitLength() { throw null; }
+ int System.Numerics.IFloatingPoint.GetSignificandByteCount() { throw null; }
+ bool System.Numerics.IFloatingPoint.TryWriteExponentBigEndian(System.Span destination, out int bytesWritten) { throw null; }
+ bool System.Numerics.IFloatingPoint.TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten) { throw null; }
+ bool System.Numerics.IFloatingPoint.TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten) { throw null; }
+ bool System.Numerics.IFloatingPoint.TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten) { throw null; }
+ static bool System.Numerics.INumberBase.IsCanonical(System.Numerics.BFloat16 value) { throw null; }
+ static bool System.Numerics.INumberBase.IsComplexNumber(System.Numerics.BFloat16 value) { throw null; }
+ static bool System.Numerics.INumberBase.IsImaginaryNumber(System.Numerics.BFloat16 value) { throw null; }
+ static bool System.Numerics.INumberBase.IsZero(System.Numerics.BFloat16 value) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertFromChecked(TOther value, out System.Numerics.BFloat16 result) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertFromSaturating(TOther value, out System.Numerics.BFloat16 result) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertFromTruncating(TOther value, out System.Numerics.BFloat16 result) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertToChecked(System.Numerics.BFloat16 value, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TOther result) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Numerics.BFloat16 value, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TOther result) { throw null; }
+ static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Numerics.BFloat16 value, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TOther result) { throw null; }
+ public static System.Numerics.BFloat16 Tan(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 Tanh(System.Numerics.BFloat16 x) { throw null; }
+ public static System.Numerics.BFloat16 TanPi(System.Numerics.BFloat16 x) { throw null; }
+ public override string ToString() { throw null; }
+ public string ToString(System.IFormatProvider? provider) { throw null; }
+ public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }
+ public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? provider) { throw null; }
+ public static System.Numerics.BFloat16 Truncate(System.Numerics.BFloat16 x) { throw null; }
+ public bool TryFormat(System.Span utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; }
+ public bool TryFormat(System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] System.ReadOnlySpan format = default(System.ReadOnlySpan), System.IFormatProvider? provider = null) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan utf8Text, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan utf8Text, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan utf8Text, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse(System.ReadOnlySpan s, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, System.IFormatProvider? provider, out System.Numerics.BFloat16 result) { throw null; }
+ public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, out System.Numerics.BFloat16 result) { throw null; }
+ }
public static partial class BitOperations
{
[System.CLSCompliantAttribute(false)]
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj
index fdb5ae06eba71..58e53d776b7a3 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj
@@ -138,6 +138,7 @@
+
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
index 9ad2869ba5a63..d4f7475debe47 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
@@ -1692,17 +1692,17 @@ public static IEnumerable