diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index fd58d7afae6074..5edaf4060229b8 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -4379,6 +4379,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 a25bcdfc984f28..491f455098eefa 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
@@ -603,6 +603,7 @@
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs
index 6c874d8037b558..5c776c4fdcb4af 100644
--- a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -947,6 +948,10 @@ public static bool ToBoolean(ReadOnlySpan value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Half Int16BitsToHalf(short value) => new Half((ushort)(value));
+ internal static short BFloat16BitsToInt16(BFloat16 value) => (short)value._value;
+
+ internal static BFloat16 Int16BitsToBFloat16(short value) => new BFloat16((ushort)(value));
+
///
/// Converts the specified double-precision floating point number to a 64-bit unsigned integer.
///
@@ -1000,5 +1005,9 @@ public static bool ToBoolean(ReadOnlySpan value)
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Half UInt16BitsToHalf(ushort value) => new Half(value);
+
+ internal static ushort BFloat16BitsToUInt16(BFloat16 value) => value._value;
+
+ internal static BFloat16 UInt16BitsToBFloat16(ushort value) => new BFloat16(value);
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs
index 105ded07251522..516f61d4e5b0f2 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Double.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs
@@ -162,6 +162,8 @@ internal static ulong ExtractTrailingSignificandFromBits(ulong bits)
return bits & TrailingSignificandMask;
}
+ internal static double CreateDouble(bool sign, ushort exp, ulong sig) => BitConverter.UInt64BitsToDouble((sign ? SignMask : 0UL) + ((ulong)exp << BiasedExponentShift) + sig);
+
/// Determines whether the specified value is finite (zero, subnormal, or normal).
/// This effectively checks the value is not NaN and not infinite.
[NonVersionable]
diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs
index f1e653e60e1fa5..2b4b9579282fbc 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Half.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs
@@ -738,7 +738,7 @@ 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
+ // The maximum infinitely precise value that will round down to MaxValue
const float MaxHalfValueBelowInfinity = 65520.0f;
// Mask for exponent bits in Half
const uint ExponentMask = BiasedExponentMask;
@@ -1015,7 +1015,7 @@ public static explicit operator double(Half value)
exp -= 1;
}
- return CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42);
+ return double.CreateDouble(sign, (ushort)(exp + 0x3F0), (ulong)sig << 42);
}
/// Explicitly converts a half-precision floating-point value to its nearest representable value.
@@ -1177,10 +1177,6 @@ private static double CreateDoubleNaN(bool sign, ulong significand)
return BitConverter.UInt64BitsToDouble(signInt | NaNBits | sigInt);
}
- private static float CreateSingle(bool sign, byte exp, uint sig) => BitConverter.UInt32BitsToSingle(((sign ? 1U : 0U) << float.SignShift) + ((uint)exp << float.BiasedExponentShift) + sig);
-
- private static double CreateDouble(bool sign, ushort exp, ulong sig) => BitConverter.UInt64BitsToDouble(((sign ? 1UL : 0UL) << double.SignShift) + ((ulong)exp << double.BiasedExponentShift) + sig);
-
#endregion
//
@@ -1360,7 +1356,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)
@@ -2339,7 +2335,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;
@@ -2351,15 +2347,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 bb80ebd3ff67a2..3748792c1784d3 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 00000000000000..1effc397dc816b
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BFloat16.cs
@@ -0,0 +1,2152 @@
+// 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, DefaultParseStyle, 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, DefaultParseStyle, 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, DefaultParseStyle, 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, DefaultParseStyle, 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, DefaultParseStyle, 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 maximum infinitely precise value that will round down to MaxValue
+ const double MaxBFloat16ValueBelowInfinity = 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(MaxBFloat16ValueBelowInfinity, 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);
+ }
+
+ ///
+ /// Rounds a number to shorter length with the midpoint-to-even rule.
+ ///
+ /// The integer type to operate with.
+ /// The payload number. Can be either actual unsigned integer, or (non-NaN) IEEE754 binary fp type.
+ /// The length of trailing bits to round up. Should be constant.
+ /// Rounded payload bits, right shifted by and aligns to LSB.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static TInteger RoundMidpointToEven(TInteger value, int trailingLength)
+ where TInteger : unmanaged, IBinaryInteger
+ {
+ TInteger lower = value & ((TInteger.One << trailingLength) - TInteger.One);
+ TInteger upper = value >>> trailingLength;
+
+ // Determine the increment for rounding
+ // When upper is even, midpoint will tie to no increment, which is effectively a decrement of lower
+ TInteger lowerShift = (~upper) & (lower >>> (trailingLength - 1)) & TInteger.One; // Upper is even & lower>=midpoint (not 0)
+ lower -= lowerShift;
+ TInteger increment = lower >>> (trailingLength - 1);
+ // Do the increment, MaxValue will be correctly increased to Infinity
+ upper += increment;
+
+ return upper;
+ }
+
+ private static unsafe BFloat16 RoundFromSigned(TInteger value)
+ where TInteger : unmanaged, IBinaryInteger, ISignedNumber
+ {
+ bool sign = TInteger.IsNegative(value);
+ TInteger abs = TInteger.IsNegative(value) ? -value : value;
+
+ int scale = int.CreateTruncating(TInteger.LeadingZeroCount(abs));
+ TInteger alignedValue = abs << scale;
+ TInteger significandBits = RoundMidpointToEven(alignedValue, sizeof(TInteger) * 8 - SignificandLength);
+
+ // Leverage FPU to calculate the value significandBits * 2^(size-SignificandLength-scale), for proper handling of 0 and carrying
+ // Use int->float conversion which usually has better FPU support
+ float significand = (float)int.CreateTruncating(significandBits);
+ // Craft the value 2^(size-SignificandLength-scale)
+ float scaleFactor = float.CreateSingle(sign, (byte)(sizeof(TInteger) * 8 - SignificandLength - scale + float.ExponentBias), 0);
+ float roundedValue = significand * scaleFactor;
+
+ uint roundedValueBits = BitConverter.SingleToUInt32Bits(roundedValue);
+ Debug.Assert((ushort)roundedValueBits == 0); // The value should be properly rounded
+ return new BFloat16((ushort)(roundedValueBits >> 16));
+ }
+
+ /// 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) => RoundFromSigned(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) => RoundFromSigned(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) => RoundFromSigned(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) => RoundFromSigned(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 roundedBits = RoundMidpointToEven(bits, 16);
+
+ // Only do rounding for non-NaN
+ return new BFloat16((ushort)(!float.IsNaN(value) ? roundedBits : (bits >> 16)));
+ }
+
+ private static unsafe BFloat16 RoundFromUnsigned(TInteger value)
+ where TInteger : unmanaged, IBinaryInteger, IUnsignedNumber
+ {
+ int scale = int.CreateTruncating(TInteger.LeadingZeroCount(value));
+ TInteger alignedValue = value << scale;
+ TInteger significandBits = RoundMidpointToEven(alignedValue, sizeof(TInteger) * 8 - SignificandLength);
+
+ // Leverage FPU to calculate the value significandBits * 2^(size-SignificandLength-scale), for proper handling of 0 and carrying
+ // Use int->float conversion which usually has better FPU support
+ float significand = (float)int.CreateTruncating(significandBits);
+ // Craft the value 2^(size-SignificandLength-scale)
+ float scaleFactor = float.CreateSingle(false, (byte)(sizeof(TInteger) * 8 - SignificandLength - scale + float.ExponentBias), 0);
+ float roundedValue = significand * scaleFactor;
+
+ uint roundedValueBits = BitConverter.SingleToUInt32Bits(roundedValue);
+ Debug.Assert((ushort)roundedValueBits == 0); // The value should be properly rounded
+ return new BFloat16((ushort)(roundedValueBits >> 16));
+ }
+
+ /// 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) => RoundFromUnsigned(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) => RoundFromUnsigned(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) => RoundFromUnsigned(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) => RoundFromUnsigned(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);
+
+ /// Explicitly converts a value to its nearest representable value.
+ /// The value to convert.
+ /// converted to its nearest representable value.
+ public static explicit operator Half(BFloat16 value) => (Half)(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 BFloat16 (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)float.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)float.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)float.Ceiling((float)x);
+
+ ///
+ public static BFloat16 Floor(BFloat16 x) => (BFloat16)float.Floor((float)x);
+
+ ///
+ public static BFloat16 Round(BFloat16 x) => (BFloat16)float.Round((float)x);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, int digits) => (BFloat16)float.Round((float)x, digits);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, MidpointRounding mode) => (BFloat16)float.Round((float)x, mode);
+
+ ///
+ public static BFloat16 Round(BFloat16 x, int digits, MidpointRounding mode) => (BFloat16)float.Round((float)x, digits, mode);
+
+ ///
+ public static BFloat16 Truncate(BFloat16 x) => (BFloat16)float.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)float.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)float.FusedMultiplyAdd((float)left, (float)right, (float)addend);
+
+ ///
+ public static BFloat16 Ieee754Remainder(BFloat16 left, BFloat16 right) => (BFloat16)float.Ieee754Remainder((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.LeadingZeroCount(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)float.ReciprocalEstimate((float)x);
+
+ ///
+ public static BFloat16 ReciprocalSqrtEstimate(BFloat16 x) => (BFloat16)float.ReciprocalSqrtEstimate((float)x);
+
+ ///
+ public static BFloat16 ScaleB(BFloat16 x, int n) => (BFloat16)float.ScaleB((float)x, n);
+
+ // ///
+ // public static BFloat16 Compound(BFloat16 x, BFloat16 n) => (BFloat16)float.Compound((float)x, (float)n);
+
+ //
+ // IHyperbolicFunctions
+ //
+
+ ///
+ public static BFloat16 Acosh(BFloat16 x) => (BFloat16)float.Acosh((float)x);
+
+ ///
+ public static BFloat16 Asinh(BFloat16 x) => (BFloat16)float.Asinh((float)x);
+
+ ///
+ public static BFloat16 Atanh(BFloat16 x) => (BFloat16)float.Atanh((float)x);
+
+ ///
+ public static BFloat16 Cosh(BFloat16 x) => (BFloat16)float.Cosh((float)x);
+
+ ///
+ public static BFloat16 Sinh(BFloat16 x) => (BFloat16)float.Sinh((float)x);
+
+ ///
+ public static BFloat16 Tanh(BFloat16 x) => (BFloat16)float.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)float.Log((float)x);
+
+ ///
+ public static BFloat16 Log(BFloat16 x, BFloat16 newBase) => (BFloat16)float.Log((float)x, (float)newBase);
+
+ ///
+ public static BFloat16 Log10(BFloat16 x) => (BFloat16)float.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)float.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)float.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)float.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)float.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);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static bool TryConvertFrom(TOther value, out BFloat16 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(double))
+ {
+ double actualValue = (double)(object)value;
+ result = (BFloat16)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 if (typeof(TOther) == typeof(sbyte))
+ {
+ sbyte actualValue = (sbyte)(object)value;
+ result = 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(byte))
+ {
+ byte actualValue = (byte)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(char))
+ {
+ char actualValue = (char)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ushort))
+ {
+ ushort actualValue = (ushort)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(uint))
+ {
+ uint actualValue = (uint)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(ulong))
+ {
+ ulong actualValue = (ulong)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(UInt128))
+ {
+ UInt128 actualValue = (UInt128)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(nuint))
+ {
+ nuint actualValue = (nuint)(object)value;
+ result = (BFloat16)actualValue;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(decimal))
+ {
+ decimal actualValue = (decimal)(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(double))
+ {
+ double actualResult = (double)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(float))
+ {
+ float actualResult = (float)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Half))
+ {
+ Half actualResult = (Half)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else 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(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 if (typeof(TOther) == typeof(decimal))
+ {
+ decimal actualResult = checked((decimal)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);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ 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(double))
+ {
+ double actualResult = (double)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(float))
+ {
+ float actualResult = (float)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else if (typeof(TOther) == typeof(Half))
+ {
+ Half actualResult = (Half)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
+ else 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)float.Pow((float)x, (float)y);
+
+ //
+ // IRootFunctions
+ //
+
+ ///
+ public static BFloat16 Cbrt(BFloat16 x) => (BFloat16)float.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)float.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)float.Acos((float)x);
+
+ ///
+ public static BFloat16 AcosPi(BFloat16 x) => (BFloat16)float.AcosPi((float)x);
+
+ ///
+ public static BFloat16 Asin(BFloat16 x) => (BFloat16)float.Asin((float)x);
+
+ ///
+ public static BFloat16 AsinPi(BFloat16 x) => (BFloat16)float.AsinPi((float)x);
+
+ ///
+ public static BFloat16 Atan(BFloat16 x) => (BFloat16)float.Atan((float)x);
+
+ ///
+ public static BFloat16 AtanPi(BFloat16 x) => (BFloat16)float.AtanPi((float)x);
+
+ ///
+ public static BFloat16 Cos(BFloat16 x) => (BFloat16)float.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)float.Sin((float)x);
+
+ ///
+ public static (BFloat16 Sin, BFloat16 Cos) SinCos(BFloat16 x)
+ {
+ var (sin, cos) = float.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)float.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 = DefaultParseStyle, 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, DefaultParseStyle, provider);
+
+ ///
+ public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BFloat16 result) => TryParse(utf8Text, DefaultParseStyle, 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 5b95aa41dcc757..a284cb69ed3a32 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Single.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs
@@ -162,6 +162,8 @@ internal static uint ExtractTrailingSignificandFromBits(uint bits)
return bits & TrailingSignificandMask;
}
+ internal static float CreateSingle(bool sign, byte exp, uint sig) => BitConverter.UInt32BitsToSingle((sign ? SignMask : 0U) + ((uint)exp << BiasedExponentShift) + sig);
+
/// Determines whether the specified value is finite (zero, subnormal, or normal).
/// This effectively checks the value is not NaN and not infinite.
[NonVersionable]
@@ -2222,7 +2224,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.Numerics/ref/System.Runtime.Numerics.cs b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
index 5ac9e6237bea3e..f08e7b7071d326 100644
--- a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
+++ b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
@@ -93,12 +93,14 @@ namespace System.Numerics
public static explicit operator System.Numerics.BigInteger (decimal value) { throw null; }
public static explicit operator System.Numerics.BigInteger (double value) { throw null; }
public static explicit operator System.Numerics.BigInteger (System.Half value) { throw null; }
+ public static explicit operator System.Numerics.BigInteger (System.Numerics.BFloat16 value) { throw null; }
public static explicit operator byte (System.Numerics.BigInteger value) { throw null; }
public static explicit operator char (System.Numerics.BigInteger value) { throw null; }
public static explicit operator decimal (System.Numerics.BigInteger value) { throw null; }
public static explicit operator double (System.Numerics.BigInteger value) { throw null; }
public static explicit operator System.Half (System.Numerics.BigInteger value) { throw null; }
public static explicit operator System.Int128 (System.Numerics.BigInteger value) { throw null; }
+ public static explicit operator System.Numerics.BFloat16 (System.Numerics.BigInteger value) { throw null; }
public static explicit operator short (System.Numerics.BigInteger value) { throw null; }
public static explicit operator int (System.Numerics.BigInteger value) { throw null; }
public static explicit operator long (System.Numerics.BigInteger value) { throw null; }
@@ -322,6 +324,7 @@ namespace System.Numerics
public static implicit operator System.Numerics.Complex (char value) { throw null; }
public static implicit operator System.Numerics.Complex (double value) { throw null; }
public static implicit operator System.Numerics.Complex (System.Half value) { throw null; }
+ public static implicit operator System.Numerics.Complex (System.Numerics.BFloat16 value) { throw null; }
public static implicit operator System.Numerics.Complex (short value) { throw null; }
public static implicit operator System.Numerics.Complex (int value) { throw null; }
public static implicit operator System.Numerics.Complex (long value) { throw null; }
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
index 2a621618fdc5b5..37ecc552ddddc8 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
@@ -1897,6 +1897,14 @@ public static explicit operator Half(BigInteger value)
return (Half)(double)value;
}
+ /// Explicitly converts a big integer to a value.
+ /// The value to convert.
+ /// converted to value.
+ public static explicit operator BFloat16(BigInteger value)
+ {
+ return (BFloat16)(double)value;
+ }
+
public static explicit operator short(BigInteger value)
{
return checked((short)((int)value));
@@ -2150,6 +2158,14 @@ public static explicit operator BigInteger(Half value)
return new BigInteger((float)value);
}
+ /// Explicitly converts a value to a big integer.
+ /// The value to convert.
+ /// converted to a big integer.
+ public static explicit operator BigInteger(BFloat16 value)
+ {
+ return new BigInteger((float)value);
+ }
+
/// Explicitly converts a value to a big integer.
/// The value to convert.
/// converted to a big integer.
@@ -3994,6 +4010,12 @@ private static bool TryConvertFromChecked(TOther value, out BigInteger r
result = checked((BigInteger)actualValue);
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualValue = (BFloat16)(object)value;
+ result = checked((BigInteger)actualValue);
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualValue = (short)(object)value;
@@ -4111,6 +4133,12 @@ private static bool TryConvertFromSaturating(TOther value, out BigIntege
result = Half.IsNaN(actualValue) ? Zero : (BigInteger)actualValue;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualValue = (BFloat16)(object)value;
+ result = BFloat16.IsNaN(actualValue) ? Zero : (BigInteger)actualValue;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualValue = (short)(object)value;
@@ -4228,6 +4256,12 @@ private static bool TryConvertFromTruncating(TOther value, out BigIntege
result = Half.IsNaN(actualValue) ? Zero : (BigInteger)actualValue;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualValue = (BFloat16)(object)value;
+ result = BFloat16.IsNaN(actualValue) ? Zero : (BigInteger)actualValue;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualValue = (short)(object)value;
@@ -4341,6 +4375,12 @@ static bool INumberBase.TryConvertToChecked(BigInteger value
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (BFloat16)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualResult = checked((short)value);
@@ -4483,6 +4523,12 @@ static bool INumberBase.TryConvertToSaturating(BigInteger va
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (BFloat16)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualResult;
@@ -4688,6 +4734,12 @@ static bool INumberBase.TryConvertToTruncating(BigInteger va
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (BFloat16)value;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualResult;
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs
index e162bab1738051..23530f1f7c4784 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs
@@ -832,6 +832,14 @@ public static implicit operator Complex(Half value)
return new Complex((double)value, 0.0);
}
+ /// Implicitly converts a value to a double-precision complex number.
+ /// The value to convert.
+ /// converted to a double-precision complex number.
+ public static implicit operator Complex(BFloat16 value)
+ {
+ return new Complex((double)value, 0.0);
+ }
+
public static implicit operator Complex(short value)
{
return new Complex(value, 0.0);
@@ -1528,6 +1536,12 @@ private static bool TryConvertFrom(TOther value, out Complex result)
result = actualValue;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualValue = (BFloat16)(object)value;
+ result = actualValue;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualValue = (short)(object)value;
@@ -1661,6 +1675,12 @@ static bool INumberBase.TryConvertToChecked(Complex value, [May
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (value.m_imaginary != 0) ? BFloat16.NaN : (BFloat16)value.m_real;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
if (value.m_imaginary != 0)
@@ -1854,6 +1874,12 @@ static bool INumberBase.TryConvertToSaturating(Complex value, [
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (BFloat16)value.m_real;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualResult = (value.m_real >= short.MaxValue) ? short.MaxValue :
@@ -1990,6 +2016,12 @@ static bool INumberBase.TryConvertToTruncating(Complex value, [
result = (TOther)(object)actualResult;
return true;
}
+ else if (typeof(TOther) == typeof(BFloat16))
+ {
+ BFloat16 actualResult = (BFloat16)value.m_real;
+ result = (TOther)(object)actualResult;
+ return true;
+ }
else if (typeof(TOther) == typeof(short))
{
short actualResult = (value.m_real >= short.MaxValue) ? short.MaxValue :
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index e1d6c46cbfe499..fbd61d905ac0fd 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -11176,6 +11176,245 @@ 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.Half(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 30556ca473ccfc..a553e9927b009d 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
@@ -140,6 +140,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 9ad2869ba5a630..d4f7475debe471 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