From 48ba63e9bb351e77ff74472bf14d528eea57636e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 27 Apr 2022 07:16:31 -0700 Subject: [PATCH 01/35] Rename to GetShortestBitLength and move the floating-point variants down to IFloatingPoint --- accepted/2021/statics-in-interfaces/README.md | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index e386ea495..cd212d7bd 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -854,10 +854,10 @@ namespace System.Numerics // These methods allow getting the underlying bytes that represent the binary integer - long GetBitLength(); - int GetByteCount(); + long GetShortestBitLength(); + bool TryWriteLittleEndian(Span destination, out int bytesWritten); int WriteLittleEndian(byte[] destination); @@ -923,6 +923,32 @@ namespace System.Numerics static abstract TSelf Round(TSelf x, int digits, MidpointRounding mode); static abstract TSelf Truncate(TSelf x); + + // These methods allow getting the underlying bytes that represent the IEEE 754 floating-point + + long GetExponentShortestBitLength(); + + int GetExponentByteCount(); + + long GetSignificandShortestBitLength(); + + int GetSignificandByteCount(); + + bool TryWriteExponentLittleEndian(Span destination, out int bytesWritten); + + bool TryWriteSignificandLittleEndian(Span destination, out int bytesWritten); + + int WriteExponentLittleEndian(byte[] destination); + + int WriteExponentLittleEndian(byte[] destination, int startIndex); + + int WriteExponentLittleEndian(Span destination); + + int WriteSignificandLittleEndian(byte[] destination); + + int WriteSignificandLittleEndian(byte[] destination, int startIndex); + + int WriteSignificandLittleEndian(Span destination); } public interface IFloatingPointIeee754 @@ -1011,32 +1037,6 @@ namespace System.Numerics static abstract TSelf MinNumber(TSelf x, TSelf y); - // These methods allow getting the underlying bytes that represent the IEEE 754 floating-point - - long GetExponentBitLength(); - - int GetExponentByteCount(); - - long GetSignificandBitLength(); - - int GetSignificandByteCount(); - - bool TryWriteExponentLittleEndian(Span destination, out int bytesWritten); - - bool TryWriteSignificandLittleEndian(Span destination, out int bytesWritten); - - int WriteExponentLittleEndian(byte[] destination); - - int WriteExponentLittleEndian(byte[] destination, int startIndex); - - int WriteExponentLittleEndian(Span destination); - - int WriteSignificandLittleEndian(byte[] destination); - - int WriteSignificandLittleEndian(byte[] destination, int startIndex); - - int WriteSignificandLittleEndian(Span destination); - // The majority of the IEEE required operations are listed below // This doesn't include the recommended operations such as sin, cos, acos, etc From 121cfb09a4d67a7dc910a63ccc48782caedb5894 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 13:12:19 -0700 Subject: [PATCH 02/35] Track CLong, CULong, and NFloat as well as ensure annotations are up to date --- accepted/2021/statics-in-interfaces/README.md | 735 ++++++++++++++---- 1 file changed, 592 insertions(+), 143 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index cd212d7bd..ce3ef3ff6 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -282,7 +282,9 @@ interface "IVector" class "BigInteger" class "Byte" class "Char" +class "CLong" class "Complex" +class "CULong" class "DateOnly" class "DateTime" class "DateTimeOffset" @@ -295,6 +297,7 @@ class "Int16" class "Int32" class "Int64" class "IntPtr" +class "NFloat" class "Object" class "SByte" class "Single" @@ -322,12 +325,22 @@ class "Vector4" "IUnsignedNumber" <|-- "Byte" "ValueType" <|-- "Byte" +"IBinaryInteger" <|-- "CLong" +"IMinMaxValue" <|-- "CLong" +"IUnsignedNumber" <|-- "CLong" +"ValueType" <|-- "CLong" + "IBinaryInteger" <|-- "Char" "IConvertible" <|-- "Char" "IMinMaxValue" <|-- "Char" "IUnsignedNumber" <|-- "Char" "ValueType" <|-- "Char" +"IBinaryInteger" <|-- "CULong" +"IMinMaxValue" <|-- "CULong" +"IUnsignedNumber" <|-- "CULong" +"ValueType" <|-- "CULong" + "IAdditionOperators" <|-- "Complex" "IDivisionOperators" <|-- "Complex" "IDivisionOperators" <|-- "Complex" @@ -421,6 +434,11 @@ class "Vector4" "ISerializable" <|-- "IntPtr" "ValueType" <|-- "IntPtr" +"IBinaryFloatingPointIeee754" <|-- "NFloat" +"IConvertible" <|-- "NFloat" +"IMinMaxValue" <|-- "NFloat" +"ValueType" <|-- "NFloat" + "IBinaryInteger" <|-- "SByte" "IConvertible" <|-- "SByte" "IMinMaxValue" <|-- "SByte" @@ -714,8 +732,6 @@ namespace System.Numerics { static abstract TSelf Exp(TSelf x); - // The following methods are approved but not yet implemented in the libraries - static abstract TSelf ExpM1(TSelf x); static abstract TSelf Exp2(TSelf x); @@ -754,8 +770,6 @@ namespace System.Numerics static abstract TSelf Log10(TSelf x); - // The following methods are approved but not yet implemented in the libraries - static abstract TSelf LogP1(TSelf x); static abstract TSelf Log2P1(TSelf x); @@ -1412,18 +1426,18 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI - // * IBinaryNumber // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) // * IComparable // Existing @@ -1532,18 +1546,18 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI - // * TSelf LeadingZeroCount(TSelf) + // * int GetByteCount() + // * long GetShortestBitLength() // ? Explicit + // * TSelf LeadingZeroCount(TSelf) // ? Explicit // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI - // * IBinaryNumber // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) // * IComparable // Existing @@ -1790,11 +1804,23 @@ namespace System // * IFloatingPoint // * TSelf Ceiling(TSelf) // * Existing // * TSelf Floor(TSelf) // * Existing + // * int GetExponentByteCount() // ? Explicit + // * long GetExponentShortestBitLength() // ? Explicit + // * int GetSignificandByteCount() // ? Explicit + // * long GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * Existing // * TSelf Round(TSelf, int) // * Existing // * TSelf Round(TSelf, MidpointRounding) // * Existing // * TSelf Round(TSelf, int, MidpointRounding) // * Existing // * TSelf Truncate(TSelf) // * Existing + // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentLittleEndian(byte[]) // ? Explicit + // * int WriteExponentLittleEndian(byte[], int) // ? Explicit + // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandLittleEndian(byte[]) // ? Explicit + // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit + // * int WriteSignificandLittleEndian(Span) // ? Explicit // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * IIncrementOperators @@ -1922,19 +1948,31 @@ namespace System // * bool Equals(TSelf) // * Existing // * IExponentialFunctions // * TSelf Exp(TSelf) - // * TSelf ExpM1(TSelf) // Approved - NYI - // * TSelf Exp2(TSelf) // Approved - NYI - // * TSelf Exp2M1(TSelf) // Approved - NYI - // * TSelf Exp10(TSelf) // Approved - NYI - // * TSelf Exp10M1(TSelf) // Approved - NYI + // * TSelf ExpM1(TSelf) + // * TSelf Exp2(TSelf) + // * TSelf Exp2M1(TSelf) + // * TSelf Exp10(TSelf) + // * TSelf Exp10M1(TSelf) // * IFloatingPoint // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) + // * int GetExponentByteCount() // ? Explicit + // * long GetExponentShortestBitLength() // ? Explicit + // * int GetSignificandByteCount() // ? Explicit + // * long GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentLittleEndian(byte[]) // ? Explicit + // * int WriteExponentLittleEndian(byte[], int) // ? Explicit + // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandLittleEndian(byte[]) // ? Explicit + // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit + // * int WriteSignificandLittleEndian(Span) // ? Explicit // * IFloatingPointIeee754 // * TSelf E { get; } // ? Explicit // * TSelf Epsilon { get; } // ? Explicit @@ -1948,10 +1986,6 @@ namespace System // * TSelf BitIncrement(TSelf) // * TSelf Compound(TSelf, TSelf) // Approved - NYI // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) - // * long GetExponentBitLength() // Approved - NYI - // * int GetExponentByteCount() // Approved - NYI - // * long GetSignificandBitLength() // Approved - NYI - // * int GetSignificandByteCount() // Approved - NYI // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) // * bool IsFinite(TSelf) // * Existing @@ -1961,21 +1995,13 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSubnormal(TSelf) // * Existing - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MaxNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinNumber(TSelf, TSelf) // Approved - NYI + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) - // * bool TryWriteExponentLittleEndian(byte[], out int) // Approved - NYI - // * bool TryWriteSignificandLittleEndian(byte[], out int) // Approved - NYI - // * int WriteExponentLittleEndian(byte[]) // Approved - NYI - // * int WriteExponentLittleEndian(byte[], int) // Approved - NYI - // * int WriteExponentLittleEndian(Span) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[]) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[], int) // Approved - NYI - // * int WriteSignificandLittleEndian(Span) // Approved - NYI // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * IHyperbolicFunctions @@ -1988,11 +2014,11 @@ namespace System // * ILogarithmicFunctions // * TSelf Log(TSelf) // * TSelf Log(TSelf, TSelf) - // * TSelf LogP1(TSelf) // Approved - NYI + // * TSelf LogP1(TSelf) // * TSelf Log2(TSelf) - // * TSelf Log2P1(TSelf) // Approved - NYI + // * TSelf Log2P1(TSelf) // * TSelf Log10(TSelf) - // * TSelf Log10P1(TSelf) // Approved - NYI + // * TSelf Log10P1(TSelf) // * INumber // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) @@ -2136,19 +2162,31 @@ namespace System // * bool Equals(TSelf) // * Existing // * IExponentialFunctions // * TSelf Exp(TSelf) - // * TSelf ExpM1(TSelf) // Approved - NYI - // * TSelf Exp2(TSelf) // Approved - NYI - // * TSelf Exp2M1(TSelf) // Approved - NYI - // * TSelf Exp10(TSelf) // Approved - NYI - // * TSelf Exp10M1(TSelf) // Approved - NYI + // * TSelf ExpM1(TSelf) + // * TSelf Exp2(TSelf) + // * TSelf Exp2M1(TSelf) + // * TSelf Exp10(TSelf) + // * TSelf Exp10M1(TSelf) // * IFloatingPoint // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) + // * int GetExponentByteCount() // ? Explicit + // * long GetExponentShortestBitLength() // ? Explicit + // * int GetSignificandByteCount() // ? Explicit + // * long GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentLittleEndian(byte[]) // ? Explicit + // * int WriteExponentLittleEndian(byte[], int) // ? Explicit + // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandLittleEndian(byte[]) // ? Explicit + // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit + // * int WriteSignificandLittleEndian(Span) // ? Explicit // * IFloatingPointIeee754 // * TSelf E { get; } // * TSelf Epsilon { get; } // * Existing @@ -2162,10 +2200,6 @@ namespace System // * TSelf BitIncrement(TSelf) // * TSelf Compound(TSelf, TSelf) // Approved - NYI // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) - // * long GetExponentBitLength() // Approved - NYI - // * int GetExponentByteCount() // Approved - NYI - // * long GetSignificandBitLength() // Approved - NYI - // * int GetSignificandByteCount() // Approved - NYI // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) // * bool IsFinite(TSelf) // * Existing @@ -2175,21 +2209,13 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSubnormal(TSelf) // * Existing - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MaxNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinNumber(TSelf, TSelf) // Approved - NYI + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) - // * bool TryWriteExponentLittleEndian(byte[], out int) // Approved - NYI - // * bool TryWriteSignificandLittleEndian(byte[], out int) // Approved - NYI - // * int WriteExponentLittleEndian(byte[]) // Approved - NYI - // * int WriteExponentLittleEndian(byte[], int) // Approved - NYI - // * int WriteExponentLittleEndian(Span) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[]) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[], int) // Approved - NYI - // * int WriteSignificandLittleEndian(Span) // Approved - NYI // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * IHyperbolicFunctions @@ -2205,11 +2231,11 @@ namespace System // * ILogarithmicFunctions // * TSelf Log(TSelf) // * TSelf Log(TSelf, TSelf) - // * TSelf LogP1(TSelf) // Approved - NYI + // * TSelf LogP1(TSelf) // * TSelf Log2(TSelf) - // * TSelf Log2P1(TSelf) // Approved - NYI + // * TSelf Log2P1(TSelf) // * TSelf Log10(TSelf) - // * TSelf Log10P1(TSelf) // Approved - NYI + // * TSelf Log10P1(TSelf) // * IModulusOperators // * TSelf operator %(TSelf, TSelf) // * IMultiplyOperators @@ -2348,18 +2374,18 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI - // * IBinaryNumber // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber // ? Explicit // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) // * IComparable // Existing @@ -2471,17 +2497,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -2594,17 +2620,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -2709,17 +2735,17 @@ namespace System // // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -2835,17 +2861,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -2965,19 +2991,31 @@ namespace System // * bool Equals(TSelf) // * Existing // * IExponentialFunctions // * TSelf Exp(TSelf) - // * TSelf ExpM1(TSelf) // Approved - NYI - // * TSelf Exp2(TSelf) // Approved - NYI - // * TSelf Exp2M1(TSelf) // Approved - NYI - // * TSelf Exp10(TSelf) // Approved - NYI - // * TSelf Exp10M1(TSelf) // Approved - NYI + // * TSelf ExpM1(TSelf) + // * TSelf Exp2(TSelf) + // * TSelf Exp2M1(TSelf) + // * TSelf Exp10(TSelf) + // * TSelf Exp10M1(TSelf) // * IFloatingPoint // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) + // * int GetExponentByteCount() // ? Explicit + // * long GetExponentShortestBitLength() // ? Explicit + // * int GetSignificandByteCount() // ? Explicit + // * long GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentLittleEndian(byte[]) // ? Explicit + // * int WriteExponentLittleEndian(byte[], int) // ? Explicit + // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandLittleEndian(byte[]) // ? Explicit + // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit + // * int WriteSignificandLittleEndian(Span) // ? Explicit // * IFloatingPointIeee754 // * TSelf E { get; } // ? Explicit // * TSelf Epsilon { get; } // ? Explicit @@ -2991,10 +3029,6 @@ namespace System // * TSelf BitIncrement(TSelf) // * TSelf Compound(TSelf, TSelf) // Approved - NYI // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) - // * long GetExponentBitLength() // Approved - NYI - // * int GetExponentByteCount() // Approved - NYI - // * long GetSignificandBitLength() // Approved - NYI - // * int GetSignificandByteCount() // Approved - NYI // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) // * bool IsFinite(TSelf) // * Existing @@ -3004,21 +3038,13 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSubnormal(TSelf) // * Existing - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MaxNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // Approved - NYI - // * TSelf MinNumber(TSelf, TSelf) // Approved - NYI + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) - // * bool TryWriteExponentLittleEndian(byte[], out int) // Approved - NYI - // * bool TryWriteSignificandLittleEndian(byte[], out int) // Approved - NYI - // * int WriteExponentLittleEndian(byte[]) // Approved - NYI - // * int WriteExponentLittleEndian(byte[], int) // Approved - NYI - // * int WriteExponentLittleEndian(Span) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[]) // Approved - NYI - // * int WriteSignificandLittleEndian(byte[], int) // Approved - NYI - // * int WriteSignificandLittleEndian(Span) // Approved - NYI // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * IHyperbolicFunctions @@ -3031,11 +3057,11 @@ namespace System // * ILogarithmicFunctions // * TSelf Log(TSelf) // * TSelf Log(TSelf, TSelf) - // * TSelf LogP1(TSelf) // Approved - NYI + // * TSelf LogP1(TSelf) // * TSelf Log2(TSelf) - // * TSelf Log2P1(TSelf) // Approved - NYI + // * TSelf Log2P1(TSelf) // * TSelf Log10(TSelf) - // * TSelf Log10P1(TSelf) // Approved - NYI + // * TSelf Log10P1(TSelf) // * INumber // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) @@ -3264,17 +3290,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -3384,17 +3410,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -3611,19 +3637,23 @@ namespace System // * TSelf operator +(TSelf) // Implicitly Implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } // * Existing + // * TSelf MinValue { get; } // * Existing + // // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -3637,9 +3667,6 @@ namespace System // * bool Equals(TSelf) // * Existing // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing - // * IMinMaxValue - // * TSelf MaxValue { get; } // * Existing - // * TSelf MinValue { get; } // * Existing // * INumber // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) @@ -3713,6 +3740,428 @@ namespace System.Numerics } } +namespace System.Runtime.InteropServices +{ + public struct CLong + : IBinaryInteger, + IMinMaxValue, + ISignedNumber + { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * One { get; } + // * Zero { get; } + // * ISignedNumber + // * TSelf NegativeOne { get; } + + // Implicitly Implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } + // * TSelf MinValue { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * IShiftOperators + // * TSelf operator <<(TSelf, int) + // * TSelf operator >>(TSelf, int) + // * TSelf operator >>>(TSelf, int) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + // + // * IBinaryInteger + // * (TSelf, TSelf) DivRem(TSelf, TSelf) + // * int GetShortestByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit + // * TSelf LeadingZeroCount(TSelf) + // * TSelf PopCount(TSelf) + // * TSelf RotateLeft(TSelf, int) + // * TSelf RotateRight(TSelf, int) + // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber + // * bool IsPow2(TSelf) + // * TSelf Log2(TSelf) + // * IComparable + // * int CompareTo(object?) + // * int CompareTo(TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) // * Existing + // * bool operator !=(TSelf, TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing + // * IFormattable + // * string ToString(string?, IFormatProvider?) + // * INumber + // * TSelf Abs(TSelf) + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsNegative(TSelf) + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf Min(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) + // * int Sign(TSelf) + // * bool TryCreate(TOther, out TSelf) + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + } + + public struct CULong + : IBinaryInteger, + IMinMaxValue, + IUnsignedNumber + { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * One { get; } + // * Zero { get; } + + // Implicitly Implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } + // * TSelf MinValue { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * IShiftOperators + // * TSelf operator <<(TSelf, int) + // * TSelf operator >>(TSelf, int) + // * TSelf operator >>>(TSelf, int) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + // + // * IBinaryInteger + // * (TSelf, TSelf) DivRem(TSelf, TSelf) + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit + // * TSelf LeadingZeroCount(TSelf) + // * TSelf PopCount(TSelf) + // * TSelf RotateLeft(TSelf, int) + // * TSelf RotateRight(TSelf, int) + // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber + // * bool IsPow2(TSelf) + // * TSelf Log2(TSelf) + // * IComparable + // * int CompareTo(object?) + // * int CompareTo(TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) // * Existing + // * bool operator !=(TSelf, TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing + // * IFormattable + // * string ToString(string?, IFormatProvider?) + // * INumber + // * TSelf Abs(TSelf) // ? Explicit + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) // ? Explicit + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsNegative(TSelf) // ? Explicit + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf Min(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) + // * int Sign(TSelf) + // * bool TryCreate(TOther, out TSelf) + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + } + + public struct NFloat + : IBinaryFloatingPointIeee754, + IMinMaxValue + { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * TSelf One { get; } + // * TSelf Zero { get; } + // * ISignedNumber + // * TSelf NegativeOne { get; } + + // Implicitly implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } + // * TSelf MinValue { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + // + // * IBinaryNumber + // * bool IsPow2(TSelf) + // * TSelf Log2(TSelf) + // * IComparable + // * int CompareTo(object?) + // * int CompareTo(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) // * Existing + // * bool operator !=(TSelf, TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing + // * IExponentialFunctions + // * TSelf Exp(TSelf) + // * TSelf ExpM1(TSelf) + // * TSelf Exp2(TSelf) + // * TSelf Exp2M1(TSelf) + // * TSelf Exp10(TSelf) + // * TSelf Exp10M1(TSelf) + // * IFloatingPoint + // * TSelf Ceiling(TSelf) + // * TSelf Floor(TSelf) + // * int GetExponentByteCount() // ? Explicit + // * long GetExponentShortestBitLength() // ? Explicit + // * int GetSignificandByteCount() // ? Explicit + // * long GetSignificandShortestBitLength() // ? Explicit + // * TSelf Round(TSelf) + // * TSelf Round(TSelf, int) + // * TSelf Round(TSelf, MidpointRounding) + // * TSelf Round(TSelf, int, MidpointRounding) + // * TSelf Truncate(TSelf) + // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentLittleEndian(byte[]) // ? Explicit + // * int WriteExponentLittleEndian(byte[], int) // ? Explicit + // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandLittleEndian(byte[]) // ? Explicit + // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit + // * int WriteSignificandLittleEndian(Span) // ? Explicit + // * IFloatingPointIeee754 + // * TSelf E { get; } + // * TSelf Epsilon { get; } + // * TSelf NaN { get; } + // * TSelf NegativeInfinity { get; } + // * TSelf NegativeZero { get; } + // * TSelf Pi { get; } + // * TSelf PositiveInfinity { get; } + // * TSelf Tau { get; } + // * TSelf BitDecrement(TSelf) + // * TSelf BitIncrement(TSelf) + // * TSelf Compound(TSelf, TSelf) // Approved - NYI + // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) + // * TSelf Ieee754Remainder(TSelf, TSelf) + // * int ILogB(TSelf) + // * bool IsFinite(TSelf) + // * bool IsInfinity(TSelf) + // * bool IsNaN(TSelf) + // * bool IsNegativeInfinity(TSelf) + // * bool IsNormal(TSelf) + // * bool IsPositiveInfinity(TSelf) + // * bool IsSubnormal(TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) + // * TSelf ReciprocalEstimate(TSelf) + // * TSelf ReciprocalSqrtEstimate(TSelf) + // * TSelf ScaleB(TSelf, int) + // * IFormattable + // * string ToString(string?, IFormatProvider?) + // * IHyperbolicFunctions + // * TSelf Acosh(TSelf) + // * TSelf Asinh(TSelf) + // * TSelf Atanh(TSelf) + // * TSelf Cosh(TSelf) + // * TSelf Sinh(TSelf) + // * TSelf Tanh(TSelf) + // * ILogarithmicFunctions + // * TSelf Log(TSelf) + // * TSelf Log(TSelf, TSelf) + // * TSelf LogP1(TSelf) + // * TSelf Log2(TSelf) + // * TSelf Log2P1(TSelf) + // * TSelf Log10(TSelf) + // * TSelf Log10P1(TSelf) + // * INumber + // * TSelf Abs(TSelf) + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsNegative(TSelf) + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf Min(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) + // * int Sign(TSelf) + // * bool TryCreate(TOther, out TSelf) + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * IPowerFunctions + // * TSelf Pow(TSelf, TSelf) + // * IRootFunctions + // * TSelf Cbrt(TSelf) + // * TSelf Hypot(TSelf, TSelf) // Approved - NYI + // * TSelf Sqrt(TSelf) + // * TSelf Root(TSelf, TSelf) // Approved - NYI + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) // * Existing + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + // * ITrigonometricFunctions + // * TSelf Acos(TSelf) + // * TSelf AcosPi(TSelf) // Approved - NYI + // * TSelf Asin(TSelf) + // * TSelf AsinPi(TSelf) // Approved - NYI + // * TSelf Atan(TSelf) + // * TSelf AtanPi(TSelf) // Approved - NYI + // * TSelf Atan2(TSelf, TSelf) + // * TSelf Atan2Pi(TSelf, TSelf) // Approved - NYI + // * TSelf Cos(TSelf) + // * TSelf CosPi(TSelf) // Approved - NYI + // * TSelf Sin(TSelf) + // * (TSelf, TSelf) SinCos(TSelf) + // * TSelf SinPi(TSelf) // Approved - NYI + // * TSelf Tan(TSelf) + // * TSelf TanPi(TSelf) // Approved - NYI + } +} + namespace System.Runtime.Intrinsics { public struct Vector64 : IVector, T> From c3aa2753a5d31a3862e4428d732ef715559063ff Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 13:24:19 -0700 Subject: [PATCH 03/35] Document the DIM implementation for the `checked operators` --- accepted/2021/statics-in-interfaces/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index ce3ef3ff6..090bca2d2 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -557,7 +557,7 @@ namespace System.Numerics static abstract TResult operator +(TSelf left, TOther right); - static abstract TResult operator checked +(TSelf left, TOther right); + public static virtual TResult operator checked +(TSelf left, TOther right) => left + right; } public interface IBitwiseOperators @@ -594,7 +594,7 @@ namespace System.Numerics { static abstract TSelf operator --(TSelf value); - static abstract TSelf operator checked --(TSelf value); + public static virtual TSelf operator checked --(TSelf value) => --value; } public interface IDivisionOperators @@ -602,7 +602,7 @@ namespace System.Numerics { static abstract TResult operator /(TSelf left, TOther right); - static abstract TResult operator checked /(TSelf left, TOther right); + public static virtual TResult operator checked /(TSelf left, TOther right) => left / right; } public interface IEqualityOperators : IEquatable @@ -631,7 +631,7 @@ namespace System.Numerics static abstract TSelf operator ++(TSelf value); - static abstract TSelf operator checked ++(TSelf value); + public static virtual TSelf operator checked ++(TSelf value) => ++value; } public interface IModulusOperators @@ -657,7 +657,7 @@ namespace System.Numerics static abstract TResult operator *(TSelf left, TOther right); - static abstract TResult operator checked *(TSelf left, TOther right); + public static virtual TResult operator checked *(TSelf left, TOther right) => left * right; } public interface IShiftOperators @@ -676,7 +676,7 @@ namespace System.Numerics { static abstract TResult operator -(TSelf left, TOther right); - static abstract TResult operator checked -(TSelf left, TOther right); + public static virtual TResult operator checked -(TSelf left, TOther right) => left - right; } public interface IUnaryNegationOperators @@ -684,7 +684,7 @@ namespace System.Numerics { static abstract TResult operator -(TSelf value); - static abstract TResult operator checked -(TSelf value); + public static virtual TResult operator checked -(TSelf value) => -value; } public interface IUnaryPlusOperators From e607dc4fbbb9502672518bf0d030d6cc0fc0c237 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 13:24:45 -0700 Subject: [PATCH 04/35] Define a DIM implementation for op_UnaryPlus --- accepted/2021/statics-in-interfaces/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 090bca2d2..4f7ed2b70 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -690,7 +690,7 @@ namespace System.Numerics public interface IUnaryPlusOperators where TSelf : IUnaryPlusOperators { - static abstract TResult operator +(TSelf value); + public static virtual TResult operator +(TSelf value) => value; } } From 4405588cb9fd01bb9b001a0600adf73d7b52713d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 13:25:41 -0700 Subject: [PATCH 05/35] Add annotations questioning if a couple methods should be DIM --- accepted/2021/statics-in-interfaces/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 4f7ed2b70..9a7cd054a 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -582,11 +582,11 @@ namespace System.Numerics static abstract bool operator <(TSelf left, TOther right); - static abstract bool operator <=(TSelf left, TOther right); + static abstract bool operator <=(TSelf left, TOther right); // ? DIM static abstract bool operator >(TSelf left, TOther right); - static abstract bool operator >=(TSelf left, TOther right); + static abstract bool operator >=(TSelf left, TOther right); // ? DIM } public interface IDecrementOperators @@ -615,7 +615,7 @@ namespace System.Numerics static abstract bool operator ==(TSelf left, TOther right); - static abstract bool operator !=(TSelf left, TOther right); + static abstract bool operator !=(TSelf left, TOther right); // ? DIM } public interface IIncrementOperators From 39fb479a69aad7b6196d8758ae255e08c09b36a0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 13:39:01 -0700 Subject: [PATCH 06/35] Have the I*Functions interfaces also constrain to INumberBase and leave DIM annotations --- accepted/2021/statics-in-interfaces/README.md | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 9a7cd054a..4b711d297 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -728,23 +728,26 @@ The numeric interfaces build upon the base interfaces by defining the core abstr namespace System.Numerics { public interface IExponentialFunctions - where TSelf : IExponentialFunctions + where TSelf : IExponentialFunctions, INumberBase { + // These could have DIM implementations if they inherit + // IPowerFunctions and had access to the constant `E` + static abstract TSelf Exp(TSelf x); - static abstract TSelf ExpM1(TSelf x); + public static virtual TSelf ExpM1(TSelf x) => Exp(x) - TSelf.One; static abstract TSelf Exp2(TSelf x); - static abstract TSelf Exp2M1(TSelf x); + public static virtual TSelf Exp2M1(TSelf x) => Exp2(x) - TSelf.One; static abstract TSelf Exp10(TSelf x); - static abstract TSelf Exp10M1(TSelf x); + public static virtual TSelf Exp10M1(TSelf x) => Exp10(x) - TSelf.One; } public interface IHyperbolicFunctions - where TSelf : IHyperbolicFunctions + where TSelf : IHyperbolicFunctions, INumberBase { static abstract TSelf Acosh(TSelf x); @@ -760,31 +763,31 @@ namespace System.Numerics } public interface ILogarithmicFunctions - where TSelf : ILogarithmicFunctions + where TSelf : ILogarithmicFunctions, INumberBase { static abstract TSelf Log(TSelf x); - static abstract TSelf Log(TSelf x, TSelf newBase); + static abstract TSelf Log(TSelf x, TSelf newBase); // ? DIM - Needs special floating-point handling for NaN, One, and Zero static abstract TSelf Log2(TSelf x); static abstract TSelf Log10(TSelf x); - static abstract TSelf LogP1(TSelf x); + public static virtual TSelf LogP1(TSelf x) => Log(x + TSelf.One); - static abstract TSelf Log2P1(TSelf x); + public static virtual TSelf Log2P1(TSelf x) => Log2(x + TSelf.One); - static abstract TSelf Log10P1(TSelf x); + public static virtual TSelf Log10P1(TSelf x) => Log10(x + TSelf.One); } public interface IPowerFunctions - where TSelf : IPowerFunctions + where TSelf : IPowerFunctions, INumberBase { static abstract TSelf Pow(TSelf x, TSelf y); } public interface IRootFunctions - where TSelf : IRootFunctions + where TSelf : IRootFunctions, INumberBase { static abstract TSelf Cbrt(TSelf x); @@ -798,7 +801,7 @@ namespace System.Numerics } public interface ITrigonometricFunctions - where TSelf : ITrigonometricFunctions + where TSelf : ITrigonometricFunctions, INumberBase { static abstract TSelf Acos(TSelf x); @@ -817,6 +820,7 @@ namespace System.Numerics static abstract TSelf Tan(TSelf x); // The following methods are approved but not yet implemented in the libraries + // These could be DIM if they had access to the constant 'Pi' static abstract TSelf AcosPi(TSelf x); From 44bb2aaa9fa6b0f443fde07245f7fbf986b084e3 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 14:17:03 -0700 Subject: [PATCH 07/35] Specify DIM algorithms for several numeric interface methods --- accepted/2021/statics-in-interfaces/README.md | 202 +++++++++++++++--- 1 file changed, 176 insertions(+), 26 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 4b711d297..e36c56339 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -858,15 +858,37 @@ namespace System.Numerics // Returning int is currently what BitOperations does, however this can be cumbersome or prohibitive // in various algorithms where returning TSelf is better. - static abstract (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right); + public static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) + { + TSelf quotient = left / right; + return (quotient, (left - (quotient * right))); + } - static abstract TSelf LeadingZeroCount(TSelf value); + public static virtual TSelf LeadingZeroCount(TSelf value) + { + TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + + if (value == Zero) + { + return TSelf.Create(); + } + + return (bitCount - TSelf.One) ^ Log2(value); + } static abstract TSelf PopCount(TSelf value); - static abstract TSelf RotateLeft(TSelf value, TSelf rotateAmount); + public static virtual TSelf RotateLeft(TSelf value, TSelf rotateAmount) + { + TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + return (value << rotateAmount) | (value >> (bitCount - rotateAmount)); + } - static abstract TSelf RotateRight(TSelf value, TSelf rotateAmount); + public static virtual TSelf RotateRight(TSelf value, TSelf rotateAmount) + { + TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + return (value >> rotateAmount) | (value << (bitCount - rotateAmount)); + } static abstract TSelf TrailingZeroCount(TSelf value); @@ -874,15 +896,40 @@ namespace System.Numerics int GetByteCount(); - long GetShortestBitLength(); + long GetShortestBitLength() + { + long bitCount = (GetByteCount() * 8L); + return bitCount - long.Create(TSelf.LeadingZeroCount(this)); + } bool TryWriteLittleEndian(Span destination, out int bytesWritten); - int WriteLittleEndian(byte[] destination); - - int WriteLittleEndian(byte[] destination, int startIndex); - - int WriteLittleEndian(Span destination); + int WriteLittleEndian(byte[] destination) + { + if (!TryWriteLittleEndian(destination, out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } + + int WriteLittleEndian(byte[] destination, int startIndex) + { + if (!TryWriteLittleEndian(destination.AsSpan(startIndex), out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } + + int WriteLittleEndian(Span destination) + { + if (!TryWriteLittleEndian(destination, out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } } public interface IBinaryNumber @@ -1004,9 +1051,9 @@ namespace System.Numerics static abstract int ILogB(TSelf x); - static abstract TSelf ReciprocalEstimate(TSelf x); + public static virtual TSelf ReciprocalEstimate(TSelf x) => TSelf.One / x; - static abstract TSelf ReciprocalSqrtEstimate(TSelf x); + public static virtual TSelf ReciprocalSqrtEstimate(TSelf x) => TSelf.One / TSelf.Sqrt(x); // IEEE defines n to be an integral type, but not the size @@ -1043,18 +1090,76 @@ namespace System.Numerics static abstract bool IsSubnormal(TSelf value); + public static virtual TSelf MaxMagnitudeNumber(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax > ay) || IsNaN(ay)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? y : x; + } + + return y; + } + + public static virtual TSelf MaxNumber(TSelf x, TSelf y) + { + if (x != y) + { + if (!IsNaN(y)) + { + return y < x ? x : y; + } + + return x; + } + + return IsNegative(y) ? x : y; + } + + public static virtual TSelf MinMagnitudeNumber(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax < ay) || IsNaN(ay)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? x : y; + } + + return y; + } + + public static virtual TSelf MinNumber(TSelf x, TSelf y) + { + if (x != y) + { + if (!IsNaN(y)) + { + return x < y ? x : y; + } + + return x; + } + + return IsNegative(x) ? x : y; + } + // The following methods are approved but not yet implemented in the libraries static abstract TSelf Compound(TSelf x, TSelf n); - static abstract TSelf MaxMagnitudeNumber(TSelf x, TSelf y); - - static abstract TSelf MaxNumber(TSelf x, TSelf y); - - static abstract TSelf MinMagnitudeNumber(TSelf x, TSelf y); - - static abstract TSelf MinNumber(TSelf x, TSelf y); - // The majority of the IEEE required operations are listed below // This doesn't include the recommended operations such as sin, cos, acos, etc @@ -1198,8 +1303,15 @@ namespace System.Numerics // and convert it into an arbitrary TSelf. If you know the type of TOther, you may be able to optimize in a few ways. Otherwise, you // may have to fail and throw in the worst case. - static abstract TSelf Create(TOther value) - where TOther : INumber; + public static virtual TSelf CreateChecked(TOther value) + where TOther : INumber + { + if (!TryCreate(value, out TSelf result)) + { + throw new OverflowException(); + } + return result; + } static abstract TSelf CreateSaturating(TOther value) where TOther : INumber; @@ -1214,11 +1326,41 @@ namespace System.Numerics // Swift has an associated type that can be used here, which would require an additional type parameter in .NET // However that would hinder the reusability of these interfaces in constraints - static abstract TSelf Abs(TSelf value); + public static TSelf Abs(TSelf value) + { + if (IsNegative(value)) + { + return checked(-value); + } + return value; + } + + public static TSelf Clamp(TSelf value, TSelf min, TSelf max) + { + if (min > max) + { + throw new ArgumentException("min cannot be greater than max"); + } + + TSelf result = value; - static abstract TSelf Clamp(TSelf value, TSelf min, TSelf max); + result = Max(result, min); + result = Min(result, max); - static abstract TSelf CopySign(TSelf value, TSelf sign); + return result; + } + + public static TSelf CopySign(TSelf value, TSelf sign) + { + TSelf result = value; + + if (IsNegative(value) != IsNegative(sign)) + { + result = checked(-result); + } + + return result; + } // IsEven, IsOdd, IsZero @@ -1239,7 +1381,15 @@ namespace System.Numerics // Math only exposes this Sign for signed types, but it is well-defined for unsigned types // it can simply never return -1 and only 0 or 1 instead - static abstract int Sign(TSelf value); + public static virtual int Sign(TSelf value) + { + if (value != Zero) + { + IsNegative(value) ? -1 : +1; + } + + return 0; + } static abstract bool TryCreate(TOther value, out TSelf result) where TOther : INumber; From 5011566baef2a4be17ea9785dd378ebce69825ab Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 14:21:30 -0700 Subject: [PATCH 08/35] Moving some `Is*` methods down to INumber so DIMs can be provided for more functions --- accepted/2021/statics-in-interfaces/README.md | 93 +++++++++++++++---- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index e36c56339..46589bbf2 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1074,22 +1074,6 @@ namespace System.Numerics static abstract TSelf PositiveInfinity { get; } - // The following methods are exposed on the floating-point types today - - static abstract bool IsFinite(TSelf value); - - static abstract bool IsInfinity(TSelf value); - - static abstract bool IsNaN(TSelf value); - - static abstract bool IsNegativeInfinity(TSelf value); - - static abstract bool IsNormal(TSelf value); - - static abstract bool IsPositiveInfinity(TSelf value); - - static abstract bool IsSubnormal(TSelf value); - public static virtual TSelf MaxMagnitudeNumber(TSelf x, TSelf y) { TSelf ax = Abs(x); @@ -1364,15 +1348,84 @@ namespace System.Numerics // IsEven, IsOdd, IsZero + static abstract bool IsFinite(TSelf value); + + static abstract bool IsInfinity(TSelf value); + + static abstract bool IsNaN(TSelf value); + static abstract bool IsNegative(TSelf value); - static abstract TSelf Max(TSelf x, TSelf y); + public static virtual bool IsNegativeInfinity(TSelf value) => IsNegative(value) && IsInfinity(value); + + static abstract bool IsNormal(TSelf value); - static abstract TSelf MaxMagnitude(TSelf x, TSelf y); + public static virtual bool IsPositive(TSelf value) => !IsNegative(value); - static abstract TSelf Min(TSelf x, TSelf y); + public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); + + static abstract bool IsSubnormal(TSelf value); - static abstract TSelf MinMagnitude(TSelf x, TSelf y); + public static virtual TSelf Max(TSelf x, TSelf y) + { + if (val1 != val2) + { + if (!IsNaN(val1)) + { + return val2 < val1 ? val1 : val2; + } + + return val1; + } + + return IsNegative(val2) ? val1 : val2; + } + + public static virtual TSelf MaxMagnitude(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax > ay) || IsNaN(ax)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? y : x; + } + + return y; + } + + public static virtual TSelf Min(TSelf x, TSelf y) + { + if (val1 != val2 && !IsNaN(val1)) + { + return val1 < val2 ? val1 : val2; + } + + return IsNegative(val1) ? val1 : val2; + } + + public static virtual TSelf MinMagnitude(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax < ay) || IsNaN(ax)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? x : y; + } + + return y; + } static abstract TSelf Parse(string s, NumberStyles style, IFormatProvider? provider); From 8c1af00f96e5b83945d4a133c156088d623305e8 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 14:25:05 -0700 Subject: [PATCH 09/35] Moving MaxMagnitudeNumber, MaxNumber, MinMagnitudeNumber, and MinNumber down to INumber --- accepted/2021/statics-in-interfaces/README.md | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 46589bbf2..4e56d5488 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1074,72 +1074,6 @@ namespace System.Numerics static abstract TSelf PositiveInfinity { get; } - public static virtual TSelf MaxMagnitudeNumber(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax > ay) || IsNaN(ay)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? y : x; - } - - return y; - } - - public static virtual TSelf MaxNumber(TSelf x, TSelf y) - { - if (x != y) - { - if (!IsNaN(y)) - { - return y < x ? x : y; - } - - return x; - } - - return IsNegative(y) ? x : y; - } - - public static virtual TSelf MinMagnitudeNumber(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax < ay) || IsNaN(ay)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? x : y; - } - - return y; - } - - public static virtual TSelf MinNumber(TSelf x, TSelf y) - { - if (x != y) - { - if (!IsNaN(y)) - { - return x < y ? x : y; - } - - return x; - } - - return IsNegative(x) ? x : y; - } - // The following methods are approved but not yet implemented in the libraries static abstract TSelf Compound(TSelf x, TSelf n); @@ -1399,6 +1333,39 @@ namespace System.Numerics return y; } + public static virtual TSelf MaxMagnitudeNumber(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax > ay) || IsNaN(ay)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? y : x; + } + + return y; + } + + public static virtual TSelf MaxNumber(TSelf x, TSelf y) + { + if (x != y) + { + if (!IsNaN(y)) + { + return y < x ? x : y; + } + + return x; + } + + return IsNegative(y) ? x : y; + } + public static virtual TSelf Min(TSelf x, TSelf y) { if (val1 != val2 && !IsNaN(val1)) @@ -1427,6 +1394,39 @@ namespace System.Numerics return y; } + public static virtual TSelf MinMagnitudeNumber(TSelf x, TSelf y) + { + TSelf ax = Abs(x); + TSelf ay = Abs(y); + + if ((ax < ay) || IsNaN(ay)) + { + return x; + } + + if (ax == ay) + { + return IsNegative(x) ? x : y; + } + + return y; + } + + public static virtual TSelf MinNumber(TSelf x, TSelf y) + { + if (x != y) + { + if (!IsNaN(y)) + { + return x < y ? x : y; + } + + return x; + } + + return IsNegative(x) ? x : y; + } + static abstract TSelf Parse(string s, NumberStyles style, IFormatProvider? provider); static abstract TSelf Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider); From c04ce714a26661c715f905a9a526520cc4ec06de Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 15:27:14 -0700 Subject: [PATCH 10/35] Removing some of the IFloatingPointIeee754 functions that are exposed --- accepted/2021/statics-in-interfaces/README.md | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 4e56d5488..d2147dbcb 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1092,22 +1092,8 @@ namespace System.Numerics // TowardPositive // TowardNegative // Exact - // TSelf NextUp(TSelf x); - // TSelf NextDown(TSelf x); - // TSelf Remainder(TSelf x, TSelf y); - - // 5.3.3 - // TSelf ScaleB(TSelf x, TLogBFormat n); - // TLogBFormat LogB(TSelf x); // 5.4.1 - // TSelf Addition(TSelf x, TSelf y); - // TSelf Subtraction(TSelf x, TSelf y); - // TSelf Multiplication(TSelf x, TSelf y); - // TSelf Division(TSelf x, TSelf y); - // TSelf SquareRoot(TSelf x); - // TSelf FusedMultiplyAdd(TSelf x, TSelf y, TSelf z); - // TSelf ConvertFromInt(TInt x); // TInt ConvertToInteger(TSelf x); // TiesToEven // TowardZero @@ -1120,21 +1106,10 @@ namespace System.Numerics // ExactTowardNegative // ExactTiesToAway - // 5.4.2 - // TOther ConvertFormat(TSelf x); - // TSelf ConvertFromDecimalCharacter(string s); - // string ConvertToDecimalCharacter(TSelf x, TFormat format); - // 5.4.3 // TResult ConvertFromHexCharacter(string s); // string ConvertToHexCharacter(TSelf x, TFormat format); - // 5.5.1 - // TSelf Copy(TSelf x); - // TSelf Negate(TSelf x); - // TSelf Abs(TSelf x); - // TSelf CopySign(TSelf x, TSelf y); - // 5.6.1 // bool Compare(TSelf x, TSelf y); // QuietEqual @@ -1168,12 +1143,7 @@ namespace System.Numerics // 5.7.2 // enum Class(TSelf x); // bool IsSignMinus(TSelf x); - // bool IsNormal(TSelf x); - // bool IsFinite(TSelf x); // bool IsZero(TSelf x); - // bool IsSubnormal(TSelf x); - // bool IsInfinite(TSelf x); - // bool IsNaN(TSelf x); // bool IsSignaling(TSelf x); // bool IsCanonical(TSelf x); // enum Radix(TSelf x); @@ -1194,16 +1164,6 @@ namespace System.Numerics // (TSelf, TSelf) AugmentedSubtraction(TSelf x, TSelf y); // (TSelf, TSelf) AugmentedMultiplication(TSelf x, TSelf y); - // 9.6 - // TSelf Minimum(TSelf x, TSelf y); - // TSelf MinimumNumber(TSelf x, TSelf y); - // TSelf Maximum(TSelf x, TSelf y); - // TSelf MaximumNumber(TSelf x, TSelf y); - // TSelf MinimumMagnitude(TSelf x, TSelf y); - // TSelf MinimumMagnitudeNumber(TSelf x, TSelf y); - // TSelf MaximumMagnitude(TSelf x, TSelf y); - // TSelf MaximumMagnitudeNumber(TSelf x, TSelf y); - // 9.7 // TSelf GetPayload(TSelf x); // TSelf SetPayload(TSelf x); From b957f80935d42f5c473e3ebfa901aae076e2d42b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 15:34:54 -0700 Subject: [PATCH 11/35] Ensure the types implementing the various INumber.Is* APIs are reflected --- accepted/2021/statics-in-interfaces/README.md | 172 +++++++++++++++--- 1 file changed, 144 insertions(+), 28 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index d2147dbcb..d3854edb9 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1621,7 +1621,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -1741,7 +1749,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -2005,7 +2021,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2155,13 +2179,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf MinMagnitudeNumber(TSelf, TSelf) @@ -2193,7 +2210,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2369,13 +2394,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf MinMagnitudeNumber(TSelf, TSelf) @@ -2415,7 +2433,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2569,7 +2595,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2692,7 +2726,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2815,7 +2857,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -2933,7 +2983,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -3056,7 +3114,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -3198,13 +3264,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf MinMagnitudeNumber(TSelf, TSelf) @@ -3236,7 +3295,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -3485,7 +3552,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -3605,7 +3680,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -3725,7 +3808,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -3841,7 +3932,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -4003,7 +4102,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) @@ -4116,7 +4223,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) @@ -4246,13 +4361,6 @@ namespace System.Runtime.InteropServices // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * bool IsFinite(TSelf) - // * bool IsInfinity(TSelf) - // * bool IsNaN(TSelf) - // * bool IsNegativeInfinity(TSelf) - // * bool IsNormal(TSelf) - // * bool IsPositiveInfinity(TSelf) - // * bool IsSubnormal(TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf MinMagnitudeNumber(TSelf, TSelf) @@ -4284,7 +4392,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) + // * bool IsInfinity(TSelf) + // * bool IsNaN(TSelf) // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) + // * bool IsNormal(TSelf) + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) + // * bool IsSubnormal(TSelf) // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) From 4b52c9f3481b807a60b6111cc4cccabff0ef0ab2 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 28 Apr 2022 15:41:59 -0700 Subject: [PATCH 12/35] Ensure the types implementing the various INumber.Min* and Max* APIs are reflected --- accepted/2021/statics-in-interfaces/README.md | 88 +++++++++++++++---- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index d3854edb9..7bac277ea 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1632,8 +1632,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -1760,8 +1764,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // ? Explicit // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // ? Explicit // * int Sign(TSelf) @@ -2032,8 +2040,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) @@ -2179,10 +2191,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) @@ -2221,8 +2229,12 @@ namespace System // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) @@ -2394,10 +2406,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) @@ -2444,8 +2452,12 @@ namespace System // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) @@ -2606,8 +2618,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -2737,8 +2753,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -2868,8 +2888,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -2994,8 +3018,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -3125,8 +3153,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -3264,10 +3296,6 @@ namespace System // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) @@ -3306,8 +3334,12 @@ namespace System // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) @@ -3563,8 +3595,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -3691,8 +3727,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -3819,8 +3859,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -3943,8 +3987,12 @@ namespace System // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) @@ -4113,8 +4161,12 @@ namespace System.Runtime.InteropServices // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) @@ -4234,8 +4286,12 @@ namespace System.Runtime.InteropServices // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) @@ -4361,10 +4417,6 @@ namespace System.Runtime.InteropServices // * TSelf FusedMultiplyAdd(TSelf, TSelf, TSelf) // * TSelf Ieee754Remainder(TSelf, TSelf) // * int ILogB(TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // * TSelf ReciprocalEstimate(TSelf) // * TSelf ReciprocalSqrtEstimate(TSelf) // * TSelf ScaleB(TSelf, int) @@ -4403,8 +4455,12 @@ namespace System.Runtime.InteropServices // * bool IsSubnormal(TSelf) // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) From a7d8720b92002553618bfcaeca5b9b65160ee08e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 2 May 2022 10:26:59 -0700 Subject: [PATCH 13/35] Adding Int128/UInt128 to the doc --- accepted/2021/statics-in-interfaces/README.md | 279 +++++++++++++++++- 1 file changed, 273 insertions(+), 6 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 7bac277ea..a532d6dd7 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -296,6 +296,7 @@ class "Half" class "Int16" class "Int32" class "Int64" +class "Int128" class "IntPtr" class "NFloat" class "Object" @@ -305,6 +306,7 @@ class "TimeSpan" class "UInt16" class "UInt32" class "UInt64" +class "UInt128" class "UIntPtr" class "ValueType" class "Vector" @@ -428,6 +430,12 @@ class "Vector4" "ISignedNumber" <|-- "Int64" "ValueType" <|-- "Int64" +"IBinaryInteger" <|-- "Int128" +"IConvertible" <|-- "Int128" +"IMinMaxValue" <|-- "Int128" +"ISignedNumber" <|-- "Int128" +"ValueType" <|-- "Int128" + "IBinaryInteger" <|-- "IntPtr" "IMinMaxValue" <|-- "IntPtr" "ISignedNumber" <|-- "IntPtr" @@ -489,6 +497,12 @@ class "Vector4" "IUnsignedNumber" <|-- "UInt64" "ValueType" <|-- "UInt64" +"IBinaryInteger" <|-- "UInt128" +"IConvertible" <|-- "UInt128" +"IMinMaxValue" <|-- "UInt128" +"IUnsignedNumber" <|-- "UInt128" +"ValueType" <|-- "UInt128" + "IBinaryInteger" <|-- "UIntPtr" "IMinMaxValue" <|-- "UIntPtr" "ISerializable" <|-- "UIntPtr" @@ -2910,6 +2924,133 @@ namespace System // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) } + public struct Int128 + : IBinaryInteger, + IMinMaxValue, + ISignedNumber + { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * One { get; } + // * Zero { get; } + // * ISignedNumber + // * TSelf NegativeOne { get; } + + // Implicitly Implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } + // * TSelf MinValue { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) + // * bool operator !=(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * IShiftOperators + // * TSelf operator <<(TSelf, int) + // * TSelf operator >>(TSelf, int) + // * TSelf operator >>>(TSelf, int) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + // + // * IBinaryInteger + // * (TSelf, TSelf) DivRem(TSelf, TSelf) + // * int GetByteCount() // ? Explicit + // * long GetShortestBitLength() // ? Explicit + // * TSelf LeadingZeroCount(TSelf) + // * TSelf PopCount(TSelf) + // * TSelf RotateLeft(TSelf, int) + // * TSelf RotateRight(TSelf, int) + // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber + // * bool IsPow2(TSelf) + // * TSelf Log2(TSelf) + // * IComparable + // * int CompareTo(object?) + // * int CompareTo(TSelf) + // * IEquatable + // * bool Equals(TSelf) + // * IFormattable + // * string ToString(string?, IFormatProvider?) + // * INumber + // * TSelf Abs(TSelf) + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit + // * TSelf Min(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) + // * int Sign(TSelf) + // * bool TryCreate(TOther, out TSelf) + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + } + public struct IntPtr : IBinaryInteger, IMinMaxValue, @@ -3820,17 +3961,17 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() // Approved - NYI - // * int GetByteCount() // Approved - NYI + // * long GetBitLength() + // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) // Approved - NYI - // * int WriteLittleEndian(byte[]) // Approved - NYI - // * int WriteLittleEndian(byte[], int) // Approved - NYI - // * int WriteLittleEndian(Span) // Approved - NYI + // * bool TryWriteLittleEndian(byte[], out int) + // * int WriteLittleEndian(byte[]) + // * int WriteLittleEndian(byte[], int) + // * int WriteLittleEndian(Span) // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -3881,6 +4022,132 @@ namespace System // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) } + public struct UInt128 + : IBinaryInteger, + IConvertible, + IMinMaxValue, + IUnsignedNumber + { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * One { get; } + // * Zero { get; } + + // Implicitly Implemented interfaces + // * IMinMaxValue + // * TSelf MaxValue { get; } + // * TSelf MinValue { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) + // * bool operator !=(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * IShiftOperators + // * TSelf operator <<(TSelf, int) + // * TSelf operator >>(TSelf, int) + // * TSelf operator >>>(TSelf, int) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + // + // * IBinaryInteger + // * (TSelf, TSelf) DivRem(TSelf, TSelf) + // * long GetBitLength() + // * int GetByteCount() + // * TSelf LeadingZeroCount(TSelf) + // * TSelf PopCount(TSelf) + // * TSelf RotateLeft(TSelf, int) + // * TSelf RotateRight(TSelf, int) + // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteLittleEndian(byte[], out int) + // * int WriteLittleEndian(byte[]) + // * int WriteLittleEndian(byte[], int) + // * int WriteLittleEndian(Span) + // * IBinaryNumber + // * bool IsPow2(TSelf) + // * TSelf Log2(TSelf) + // * IComparable + // * int CompareTo(object?) + // * int CompareTo(TSelf) + // * IEquatable + // * bool Equals(TSelf) + // * IFormattable + // * string ToString(string?, IFormatProvider?) + // * INumber + // * TSelf Abs(TSelf) // ? Explicit + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) // ? Explicit + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit + // * TSelf Min(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) + // * int Sign(TSelf) + // * bool TryCreate(TOther, out TSelf) + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + } + public struct UIntPtr : IBinaryInteger, IMinMaxValue, From 6689cd7549851af98f4412a469f4ec49e4df6962 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 6 May 2022 10:55:08 -0700 Subject: [PATCH 14/35] Having IBinaryInteger also implement IShiftOperators --- accepted/2021/statics-in-interfaces/README.md | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index a532d6dd7..ab360c349 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -863,7 +863,8 @@ namespace System.Numerics public interface IBinaryInteger : IBinaryNumber, - IShiftOperators + IShiftOperators, + IShiftOperators where TSelf : IBinaryInteger { // We might want to support "big multiplication" for fixed width types @@ -1592,6 +1593,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -1724,6 +1728,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -2578,6 +2585,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -2713,6 +2723,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -2848,6 +2861,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -2976,6 +2992,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -3098,6 +3117,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -3240,6 +3262,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -3682,6 +3707,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -3814,6 +3842,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -3946,6 +3977,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -4073,6 +4107,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -4193,6 +4230,9 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -4372,6 +4412,9 @@ namespace System.Runtime.InteropServices // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) @@ -4497,6 +4540,9 @@ namespace System.Runtime.InteropServices // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) // * TSelf operator <<(TSelf, int) // * TSelf operator >>(TSelf, int) // * TSelf operator >>>(TSelf, int) From 6636901a80bb22bf08589b824bc568b36c7c1848 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 10:53:41 -0700 Subject: [PATCH 15/35] Add a section covering the create/conversion APIs --- accepted/2021/statics-in-interfaces/README.md | 779 +++++++++++++++--- 1 file changed, 670 insertions(+), 109 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index ab360c349..a5431d32f 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -206,6 +206,10 @@ interface "IMultiplicativeIdentity" interface "IMultiplyOperators" interface "INumber" interface "INumberBase" +interface "INumberConverter" +interface "INumberConverterChecked" +interface "INumberConverterSaturating" +interface "INumberConverterTruncating" interface "IPowerFunctions" interface "IRootFunctions" interface "IShiftOperators" @@ -881,11 +885,11 @@ namespace System.Numerics public static virtual TSelf LeadingZeroCount(TSelf value) { - TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); if (value == Zero) { - return TSelf.Create(); + return TSelf.CreateChecked(); } return (bitCount - TSelf.One) ^ Log2(value); @@ -895,13 +899,13 @@ namespace System.Numerics public static virtual TSelf RotateLeft(TSelf value, TSelf rotateAmount) { - TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); return (value << rotateAmount) | (value >> (bitCount - rotateAmount)); } public static virtual TSelf RotateRight(TSelf value, TSelf rotateAmount) { - TSelf bitCount = TSelf.Create(value.GetByteCount() * 8L); + TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); return (value >> rotateAmount) | (value << (bitCount - rotateAmount)); } @@ -914,7 +918,7 @@ namespace System.Numerics long GetShortestBitLength() { long bitCount = (GetByteCount() * 8L); - return bitCount - long.Create(TSelf.LeadingZeroCount(this)); + return bitCount - long.CreateChecked(TSelf.LeadingZeroCount(this)); } bool TryWriteLittleEndian(Span destination, out int bytesWritten); @@ -958,7 +962,7 @@ namespace System.Numerics static abstract bool IsPow2(TSelf value); - static abstract TSelf Log2(TSelf value); + static abstract TSelf Log2(TSelf value); // "Conflicts" with ILogarithmicFunctions.Log2 } public interface IDecimalFloatingPointIeee754 @@ -1192,26 +1196,6 @@ namespace System.Numerics ISpanParsable // implies IParsable where TSelf : INumber { - // For the Create methods, there is some concern over users implementing them. It is not necessarily trivial to take an arbitrary TOther - // and convert it into an arbitrary TSelf. If you know the type of TOther, you may be able to optimize in a few ways. Otherwise, you - // may have to fail and throw in the worst case. - - public static virtual TSelf CreateChecked(TOther value) - where TOther : INumber - { - if (!TryCreate(value, out TSelf result)) - { - throw new OverflowException(); - } - return result; - } - - static abstract TSelf CreateSaturating(TOther value) - where TOther : INumber; - - static abstract TSelf CreateTruncating(TOther value) - where TOther : INumber; - // There is an open question on whether properties like IsSigned, IsBinary, IsFixedWidth, Base/Radix, and others are beneficial // We could expose them for trivial checks or users could be required to check for the corresponding correct interfaces @@ -1419,9 +1403,6 @@ namespace System.Numerics return 0; } - static abstract bool TryCreate(TOther value, out TSelf result) - where TOther : INumber; - static abstract bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out TSelf result); static abstract bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out TSelf result); @@ -1447,6 +1428,78 @@ namespace System.Numerics // Alias for AdditiveIdentity static abstract TSelf Zero { get; } + + public static TSelf CreateChecked(TOther value) + where TOther : INumberBase + { + TSelf result; + + if (TSelf.TryConvertFromChecked(value, out result)) + { + return result; + } + + if (TOther.TryConvertToChecked(value, out result)) + { + return result; + } + + throw new NotSupportedException(); + } + + static TSelf CreateSaturating(TOther value) + where TOther : INumber + { + TSelf result; + + if (TSelf.TryConvertFromSaturating(value, out result)) + { + return result; + } + + if (TOther.TryConvertToSaturating(value, out result)) + { + return result; + } + + throw new NotSupportedException(); + } + + static TSelf CreateTruncating(TOther value) + where TOther : INumber + { + TSelf result; + + if (TSelf.TryConvertFromTruncating(value, out result)) + { + return result; + } + + if (TOther.TryConvertToTruncating(value, out result)) + { + return result; + } + + throw new NotSupportedException(); + } + + protected static abstract bool TryConvertFromChecked(TOther value, out TSelf? result) + where TOther : INumber; + + protected static abstract bool TryConvertFromSaturating(TOther value, out TSelf? result) + where TOther : INumber; + + protected static abstract bool TryConvertFromTruncating(TOther value, out TSelf? result) + where TOther : INumber; + + protected static abstract bool TryConvertToChecked(TSelf value, out TOther? result) + where TOther : INumber; + + protected static abstract bool TryConvertToSaturating(TSelf value, out TOther? result) + where TOther : INumber; + + protected static abstract bool TryConvertToTruncating(TSelf value, out TOther? result) + where TOther : INumber; } public interface ISignedNumber @@ -1464,6 +1517,16 @@ namespace System.Numerics } } +namespace System.Numerics +{ + public interface INumberConverter + where T : INumber + where U : INumber + { + static abstract T Convert(U value); + } +} + namespace System.Numerics { public interface IVector @@ -1636,9 +1699,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -1659,9 +1719,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -1771,9 +1840,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -1794,9 +1860,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // ? Explicit // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // ? Explicit // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // ? Explicit // * bool TryParse(string?, IFormatProvider?, out TSelf) // ? Explicit @@ -2047,9 +2122,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2070,9 +2142,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -2236,9 +2317,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -2259,9 +2337,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -2459,9 +2546,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -2482,9 +2566,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -2628,9 +2721,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2651,9 +2741,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -2766,9 +2865,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2789,9 +2885,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -2904,9 +3009,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2927,9 +3029,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3034,9 +3145,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3057,9 +3165,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3167,9 +3284,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3190,9 +3304,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3305,9 +3428,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3328,9 +3448,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3486,9 +3615,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -3509,9 +3635,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3750,9 +3885,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3773,9 +3905,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -3885,9 +4026,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3908,9 +4046,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4020,9 +4167,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4043,9 +4187,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4149,9 +4302,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4172,9 +4322,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4280,9 +4439,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4303,9 +4459,18 @@ namespace System // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * Existing // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4457,9 +4622,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4480,9 +4642,18 @@ namespace System.Runtime.InteropServices // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4585,9 +4756,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4608,9 +4776,18 @@ namespace System.Runtime.InteropServices // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4754,9 +4931,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) // * bool IsFinite(TSelf) // * bool IsInfinity(TSelf) // * bool IsNaN(TSelf) @@ -4777,9 +4951,18 @@ namespace System.Runtime.InteropServices // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryCreate(TOther, out TSelf) // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) + // * INumberBase + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable // * TSelf Parse(string, IFormatProvider?) // * bool TryParse(string?, IFormatProvider?, out TSelf) @@ -4830,6 +5013,384 @@ namespace System.Runtime.Intrinsics } ``` +### Create and Conversion APIs explained + +For number creation and conversion, we have three different scenarios to consider. + +You have types like `Int32` which can know about other types in the same assembly, such as `Int64`. But which can't know about other types in deriving assemblies, such as `BigInteger`. This scenario is simple as you can directly check for the relevant types and do the conversions. It is possible to utilize things like `internal` to expose details allowing fast conversions and the biggest question ends up being whether to expose the conversions on type `A`, type `B`, or splitting between both. + +You have types like `BigInteger` which can know about other types in the same assembly, such as `Complex`, and types in its dependencies, such as `Int32` or `Int64`. It again can't know about other types in deriving assemblies or in completely unrelated assemblies. This scenario is likewise simple with the main difference is you likely don't have access to internals and both conversions need to be exposed on type `B`. + +Finally you have types that exist in two parallel assemblies where neither depends on the other. Imagine, for example, two standalone NuGet packages one providing a `Float128` and the other providing a `Rational` number type. This scenario is decently complex because the only way to get conversions is for one assembly to depend on the other (there-by becoming scenario 2) or for some third assembly to depend on both and provide the conversions itself. + +#### Scenario 1 + +The first scenario leads to a design that looks like this. + +```csharp +interface INumber + where TSelf : INumber +{ + public static TSelf Create(TOther value) + where TOther : INumber + { + if (!TryCreate(value, out TSelf result)) + { + throw new NotSupportedException(); + } + return result; + } + + static abstract bool TryCreate(TOther value, out TSelf? result) + where TOther : INumber; +} + +struct Int32 : INumber +{ + public static bool TryCreate(TOther value, out int result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = (int)(actualValue); + return true; + } + + return false; + } +} + +struct Int64 : INumber +{ + public static bool TryCreate(TOther value, out long result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = actualValue; + return true; + } + + return false; + } +} +``` + +It runs into the mentioned issues where the conversion fails if `TOther` is unrecognized, such as `BigInteger`: +```csharp +struct BigInteger : INumber +{ + public static bool TryCreate(TOther value, out BigInteger result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(BigInteger)) + { + BigInteger actualValue = (BigInteger)(object)(value!); + result = actualValue; + return true; + } + + return false; + } +} +``` + +There is also a nuance that this can cause "generic code explosion" and that the size of the methods become quite large, which can negatively impact JIT throughput, inlining, and other behavior. + +There is an additional problem where this actually happens 3 times. Once for `checked` (throw on overflow), once for `saturating` (clamp to Min/Max value), and once for `truncating` (take lowest n-bits). + +The code is used as follows: +```csharp +public static TResult Sum(IEnumerable values) + where T : INumber + where TResult : INumber +{ + TResult result = TResult.Zero; + + foreach (var value in values) + { + result += TResult.Create(value); + } + + return result; +} +``` + +#### Scenario 2 + +The second scenario needs to support `TOther` providing a conversion and so the design ends up changing a bit. + +```csharp +interface INumber + where TSelf : INumber +{ + public static TSelf Create(TOther value) + where TOther : INumber + { + if (!TryCreate(value, out TSelf result)) + { + throw new NotSupportedException(); + } + return result; + } + + public static bool TryCreate(TOther value, out TSelf? result) + where TOther : INumber + { + return TSelf.TryConvertFrom(value, out result) + || TOther.TryConvertTo(value, out result); + } + + +} + +struct Int32 : INumber +{ + protected static bool TryConvertFrom(TOther value, out int result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = (int)(actualValue); + return true; + } + + result = default; + return false; + } + + protected static bool TryConvertTo(int value, out TOther? result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualResult = value; + result = (TOther)(object)(actualResult); + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualResult = value; + result = (TOther)(object)(actualResult); + return true; + } + + result = default; + return false; + } +} + +struct Int64 : INumber +{ + protected static bool TryConvertFrom(TOther value, out long result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = actualValue; + return true; + } + + result = default; + return false; + } + + protected static bool TryConvertTo(long value, out TOther? result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualResult = (int)(value); + result = (TOther)(object)(actualResult); + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualResult = value; + result = (TOther)(object)(actualResult); + return true; + } + + result = default; + return false; + } +} +``` + +This also then allows creating a `Int32` or `Int64` from a `BigInteger`: +```csharp +struct BigInteger : INumber +{ + protected static bool TryConvertFrom(TOther value, out BigInteger result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualValue = (int)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualValue = (long)(object)(value!); + result = actualValue; + return true; + } + + if (typeof(TOther) == typeof(BigInteger)) + { + BigInteger actualValue = (BigInteger)(object)(value!); + result = actualValue; + return true; + } + + result = default; + return false; + } + + protected static bool TryConvertTo(BigInteger value, out TOther? result) + where TOther : INumber + { + if (typeof(TOther) == typeof(int)) + { + int actualResult = (int)(value); + result = (TOther)(object)(actualResult); + return true; + } + + if (typeof(TOther) == typeof(long)) + { + long actualResult = (long)(value); + result = (TOther)(object)(actualResult); + return true; + } + + if (typeof(TOther) == typeof(BigInteger)) + { + BigInteger actualResult = value; + result = (TOther)(object)(actualResult); + return true; + } + + result = default; + return false; + } +} +``` + +There is still the downside that two types living in different assemblies can't convert between eachother. There is likewise a new downside in that the amount of code you have to write/maintain effectively doubles, with much of it being duplicate. + +The same nuance around "generic code explosion" still exists, as does the potential negative impact on JIT throughput, inlining, etc. Additionally, there is a nuance that `TryConvertFrom` and `TryConvertTo` must be "self-contained". That is, they cannot themselves defer to `TOther` for anything or they'll risk introducing a cycle in the logic and causing a `StackOverflowException`. + +The same additional problem where this actually happens 3 times. Once for `checked` (throw on overflow), once for `saturating` (clamp to Min/Max value), and once for `truncating` (take lowest n-bits) still exists. + +The usage code remains the same. +```csharp +public static TResult Sum(IEnumerable values) + where T : INumber + where TResult : INumber +{ + TResult result = TResult.Zero; + + foreach (var value in values) + { + result += TResult.Create(value); + } + + return result; +} +``` + +#### Scenario 3 + +This brings us to the third scenario and needing some way to allow conversion between types that know nothing of eachother. + +```csharp +interface INumberConverter + where T : INumber + where U : INumber +{ + static abstract T Convert(U value); +} +``` + +This would allow the usage code to become: +```csharp +public static TResult Sum(IEnumerable values) + where T : INumber + where TResult : INumber + where TConverter : INumberConverter +{ + TResult result = TResult.Zero; + + foreach (var value in values) + { + result += TConverter.Convert(value); + } + + return result; +} +``` + +There are upsides and downsides to this last approach. The consumer of the API is able to provide the conversion behavior and decide if it should `throw`, `saturate`, or `truncate` on `overflow`, which may be undesirable to the implementor. We could expose (instead of or in addition to `INumberConverter`) `ICheckedNumberConverter`, `ISaturatingNumberConverter`, and `ITruncatingNumberConverter` to allow enforcement of a conversion behavior. + +Since C#/.NET don't have higher kinded types or associated types, we can't expose some non-generic variant that defers to the generic variant. We likewise can't easily expose a way to get an instance of the "default" number converter. + +This leaves us with the `TryConvertFrom`/`TryConvertTo` pattern for the majority of scenarios, with the ability for that to "fallback" to `IBinaryInteger.TryWriteLittleEndian`, `IFloatingPoint.TryWriteExponentLittleEndian`, and `IFloatingPoint.TryWriteSignificandLittleEndian` for some subset of completely unknown types. It also leaves us with having `INumberConverter` on top so that API implementors and consumers have a "path forward" when they are dealing with otherwise completely unrelated types. + +#### Why no `IConvertible`, `IExplicitOperators`, or `IImplicitOperators` + +We could expose these, but they have the same general limitations as the `Create` APIs. Additionally, it vastly increases the number of interfaces implemented since there are 11 primitive integer types (`byte`, `char`, `short`, `int`, `long`, `nint`, `sbyte`, `ushort`, `uint`, `ulong`, and `nuint`), 3 primitive floating-point types (`decimal`, `double`, and `float`), and some 6 other ABI primitive types (`Half`, `Int128`, `UInt128`, `NFloat`, `CLong`, and `CULong`). Supporting single-direction conversions for these requires at least 14 interfaces. Bi-directional doubles that to 24. + ### Pending Concepts There are several types which may benefit from some interface support. These include, but aren't limited to: From 35e269eb414b81d028cc8f0a4fa70dd081de5436 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 11:24:18 -0700 Subject: [PATCH 16/35] Moving the `Is*` APIs down to `INumberBase` --- accepted/2021/statics-in-interfaces/README.md | 382 +++++++++--------- 1 file changed, 191 insertions(+), 191 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index a5431d32f..dd29c369a 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1239,26 +1239,6 @@ namespace System.Numerics return result; } - // IsEven, IsOdd, IsZero - - static abstract bool IsFinite(TSelf value); - - static abstract bool IsInfinity(TSelf value); - - static abstract bool IsNaN(TSelf value); - - static abstract bool IsNegative(TSelf value); - - public static virtual bool IsNegativeInfinity(TSelf value) => IsNegative(value) && IsInfinity(value); - - static abstract bool IsNormal(TSelf value); - - public static virtual bool IsPositive(TSelf value) => !IsNegative(value); - - public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); - - static abstract bool IsSubnormal(TSelf value); - public static virtual TSelf Max(TSelf x, TSelf y) { if (val1 != val2) @@ -1483,6 +1463,26 @@ namespace System.Numerics throw new NotSupportedException(); } + // IsEven, IsOdd, IsZero + + static abstract bool IsFinite(TSelf value); + + static abstract bool IsInfinity(TSelf value); + + static abstract bool IsNaN(TSelf value); + + static abstract bool IsNegative(TSelf value); + + public static virtual bool IsNegativeInfinity(TSelf value) => IsNegative(value) && IsInfinity(value); + + static abstract bool IsNormal(TSelf value); + + public static virtual bool IsPositive(TSelf value) => !IsNegative(value); + + public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); + + static abstract bool IsSubnormal(TSelf value); + protected static abstract bool TryConvertFromChecked(TOther value, out TSelf? result) where TOther : INumber; @@ -1699,15 +1699,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -1725,6 +1716,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -1840,15 +1840,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -1866,6 +1857,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2122,15 +2122,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -2148,6 +2139,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2317,15 +2317,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegative(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) @@ -2343,6 +2334,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing + // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2546,15 +2546,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegative(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) @@ -2572,6 +2563,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing + // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2721,15 +2721,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -2747,6 +2738,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2865,15 +2865,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -2891,6 +2882,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3009,15 +3009,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -3035,6 +3026,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3145,15 +3145,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -3171,6 +3162,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3284,15 +3284,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -3310,6 +3301,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3428,15 +3428,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -3454,6 +3445,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3615,15 +3615,6 @@ namespace System // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // * Existing - // * bool IsInfinity(TSelf) // * Existing - // * bool IsNaN(TSelf) // * Existing - // * bool IsNegative(TSelf) // * Existing - // * bool IsNegativeInfinity(TSelf) // * Existing - // * bool IsNormal(TSelf) // * Existing - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // * Existing - // * bool IsSubnormal(TSelf) // * Existing // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) @@ -3641,6 +3632,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsNaN(TSelf) // * Existing + // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSubnormal(TSelf) // * Existing // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3885,15 +3885,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -3911,6 +3902,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4026,15 +4026,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4052,6 +4043,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4167,15 +4167,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4193,6 +4184,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4302,15 +4302,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4328,6 +4319,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4439,15 +4439,6 @@ namespace System // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4465,6 +4456,15 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4622,15 +4622,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4648,6 +4639,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4756,15 +4756,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit @@ -4782,6 +4773,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) // ? Explicit + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) // ? Explicit + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) From 2d89f3609b55b76326978dbe896f74e1924f7743 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 11:49:40 -0700 Subject: [PATCH 17/35] Expose `IsCanonical`, `IsSignalingNaN`, and `IsZero` as required by IEEE 754 --- accepted/2021/statics-in-interfaces/README.md | 88 ++++++++++++++++--- 1 file changed, 74 insertions(+), 14 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index dd29c369a..f57dc15db 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1161,10 +1161,6 @@ namespace System.Numerics // 5.7.2 // enum Class(TSelf x); - // bool IsSignMinus(TSelf x); - // bool IsZero(TSelf x); - // bool IsSignaling(TSelf x); - // bool IsCanonical(TSelf x); // enum Radix(TSelf x); // bool TotalOrder(TSelf x, TSelf y); // bool TotalOrderMag(TSelf x, TSelf y); @@ -1463,7 +1459,7 @@ namespace System.Numerics throw new NotSupportedException(); } - // IsEven, IsOdd, IsZero + static abstract bool IsCanonical(TSelf value); static abstract bool IsFinite(TSelf value); @@ -1481,8 +1477,12 @@ namespace System.Numerics public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); + static abstract bool IsSignalingNaN(TSelf value); + static abstract bool IsSubnormal(TSelf value); + static abstract bool IsZero(TSelf value); + protected static abstract bool TryConvertFromChecked(TOther value, out TSelf? result) where TOther : INumber; @@ -1716,6 +1716,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -1724,7 +1725,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -1857,6 +1860,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -1865,7 +1869,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2139,6 +2145,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2147,7 +2154,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2334,6 +2343,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -2342,7 +2352,9 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2563,6 +2575,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -2571,7 +2584,9 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2738,6 +2753,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2746,7 +2762,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2882,6 +2900,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -2890,7 +2909,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3026,6 +3047,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3034,7 +3056,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3162,6 +3186,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3170,7 +3195,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3301,6 +3328,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3309,7 +3337,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3445,6 +3475,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3453,7 +3484,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3632,6 +3665,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing // * bool IsNaN(TSelf) // * Existing @@ -3640,7 +3674,9 @@ namespace System // * bool IsNormal(TSelf) // * Existing // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3902,6 +3938,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -3910,7 +3947,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4043,6 +4082,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4051,7 +4091,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4184,6 +4226,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4192,7 +4235,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4319,6 +4364,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4327,7 +4373,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4456,6 +4504,7 @@ namespace System // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4464,7 +4513,9 @@ namespace System // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4639,6 +4690,7 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4647,7 +4699,9 @@ namespace System.Runtime.InteropServices // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4773,6 +4827,7 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit @@ -4781,7 +4836,9 @@ namespace System.Runtime.InteropServices // * bool IsNormal(TSelf) // ? Explicit // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4931,15 +4988,6 @@ namespace System.Runtime.InteropServices // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) - // * bool IsFinite(TSelf) - // * bool IsInfinity(TSelf) - // * bool IsNaN(TSelf) - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) - // * bool IsNormal(TSelf) - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) - // * bool IsSubnormal(TSelf) // * TSelf Max(TSelf, TSelf) // * TSelf MaxMagnitude(TSelf, TSelf) // * TSelf MaxMagnitudeNumber(TSelf, TSelf) @@ -4957,6 +5005,18 @@ namespace System.Runtime.InteropServices // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsFinite(TSelf) + // * bool IsInfinity(TSelf) + // * bool IsNaN(TSelf) + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) + // * bool IsNormal(TSelf) + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) + // * bool IsSignalingNaN(TSelf) + // * bool IsSubnormal(TSelf) + // * bool IsZero(TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) From 1d276b5d5f9febe85c2e08626b137384bbcc799a Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 11:57:16 -0700 Subject: [PATCH 18/35] Expose IsEvenInteger, IsInteger, and IsOddInteger --- accepted/2021/statics-in-interfaces/README.md | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index f57dc15db..54e81adf3 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1461,10 +1461,14 @@ namespace System.Numerics static abstract bool IsCanonical(TSelf value); + static abstract bool IsEvenInteger(TSelf value); + static abstract bool IsFinite(TSelf value); static abstract bool IsInfinity(TSelf value); + static abstract bool IsInteger(TSelf value); + static abstract bool IsNaN(TSelf value); static abstract bool IsNegative(TSelf value); @@ -1473,6 +1477,8 @@ namespace System.Numerics static abstract bool IsNormal(TSelf value); + static abstract bool IsOddInteger(TSelf value); + public static virtual bool IsPositive(TSelf value) => !IsNegative(value); public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); @@ -1717,12 +1723,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -1861,12 +1870,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -2146,12 +2158,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -2344,12 +2359,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing + // * bool IsInteger(TSelf) // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing // * bool IsNegativeInfinity(TSelf) // * Existing // * bool IsNormal(TSelf) // * Existing + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSignalingNaN(TSelf) @@ -2576,12 +2594,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing + // * bool IsInteger(TSelf) // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing // * bool IsNegativeInfinity(TSelf) // * Existing // * bool IsNormal(TSelf) // * Existing + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSignalingNaN(TSelf) @@ -2754,12 +2775,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -2901,12 +2925,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -3048,12 +3075,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -3187,12 +3217,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -3329,12 +3362,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -3476,12 +3512,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -3666,12 +3705,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // * Existing // * bool IsInfinity(TSelf) // * Existing + // * bool IsInteger(TSelf) // * bool IsNaN(TSelf) // * Existing // * bool IsNegative(TSelf) // * Existing // * bool IsNegativeInfinity(TSelf) // * Existing // * bool IsNormal(TSelf) // * Existing + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * Existing // * bool IsSignalingNaN(TSelf) @@ -3939,12 +3981,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4083,12 +4128,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4227,12 +4275,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4365,12 +4416,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4505,12 +4559,15 @@ namespace System // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4691,12 +4748,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -4828,12 +4888,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // ? Explicit // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit // * bool IsNaN(TSelf) // ? Explicit // * bool IsNegative(TSelf) // ? Explicit // * bool IsNegativeInfinity(TSelf) // ? Explicit // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // ? Explicit // * bool IsPositiveInfinity(TSelf) // ? Explicit // * bool IsSignalingNaN(TSelf) // ? Explicit @@ -5006,12 +5069,15 @@ namespace System.Runtime.InteropServices // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) // * bool IsFinite(TSelf) // * bool IsInfinity(TSelf) + // * bool IsInteger(TSelf) // * bool IsNaN(TSelf) // * bool IsNegative(TSelf) // * bool IsNegativeInfinity(TSelf) // * bool IsNormal(TSelf) + // * bool IsOddInteger(TSelf) // * bool IsPositive(TSelf) // * bool IsPositiveInfinity(TSelf) // * bool IsSignalingNaN(TSelf) From 56680456063edcb929fe05d52714671d75693acc Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 11:30:25 -0700 Subject: [PATCH 19/35] Expose a way to get the Radix --- accepted/2021/statics-in-interfaces/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 54e81adf3..db77ea4ec 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1402,6 +1402,8 @@ namespace System.Numerics // Alias for MultiplicativeIdentity static abstract TSelf One { get; } + static abstract int Radix { get; } + // Alias for AdditiveIdentity static abstract TSelf Zero { get; } From ad831b88a05dd41091f61a030267f4c810504099 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 12:07:12 -0700 Subject: [PATCH 20/35] Moving `Abs`, `MaxMagnitude`, `MaxMagnitudeNumber`, `MinMagnitude`, and `MinMagnitudeNumber` down to INumberBase --- accepted/2021/statics-in-interfaces/README.md | 394 +++++++++--------- 1 file changed, 206 insertions(+), 188 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index db77ea4ec..d3d6d648c 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1192,22 +1192,6 @@ namespace System.Numerics ISpanParsable // implies IParsable where TSelf : INumber { - // There is an open question on whether properties like IsSigned, IsBinary, IsFixedWidth, Base/Radix, and others are beneficial - // We could expose them for trivial checks or users could be required to check for the corresponding correct interfaces - - // Abs mirrors Math.Abs and returns the same type. This can fail for MinValue of signed integer types - // Swift has an associated type that can be used here, which would require an additional type parameter in .NET - // However that would hinder the reusability of these interfaces in constraints - - public static TSelf Abs(TSelf value) - { - if (IsNegative(value)) - { - return checked(-value); - } - return value; - } - public static TSelf Clamp(TSelf value, TSelf min, TSelf max) { if (min > max) @@ -1250,42 +1234,6 @@ namespace System.Numerics return IsNegative(val2) ? val1 : val2; } - public static virtual TSelf MaxMagnitude(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax > ay) || IsNaN(ax)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? y : x; - } - - return y; - } - - public static virtual TSelf MaxMagnitudeNumber(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax > ay) || IsNaN(ay)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? y : x; - } - - return y; - } - public static virtual TSelf MaxNumber(TSelf x, TSelf y) { if (x != y) @@ -1311,42 +1259,6 @@ namespace System.Numerics return IsNegative(val1) ? val1 : val2; } - public static virtual TSelf MinMagnitude(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax < ay) || IsNaN(ax)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? x : y; - } - - return y; - } - - public static virtual TSelf MinMagnitudeNumber(TSelf x, TSelf y) - { - TSelf ax = Abs(x); - TSelf ay = Abs(y); - - if ((ax < ay) || IsNaN(ay)) - { - return x; - } - - if (ax == ay) - { - return IsNegative(x) ? x : y; - } - - return y; - } - public static virtual TSelf MinNumber(TSelf x, TSelf y) { if (x != y) @@ -1399,6 +1311,29 @@ namespace System.Numerics IUnaryNegationOperators where TSelf : INumberBase { + // There is an open question on whether properties like IsSigned, IsBinary, IsFixedWidth, Base/Radix, and others are beneficial + // We could expose them for trivial checks or users could be required to check for the corresponding correct interfaces + + // Abs mirrors Math.Abs and returns the same type. This can fail for MinValue of signed integer types + // + // Swift has an associated type that can be used here, which would require an additional type parameter in .NET + // However that would hinder the reusability of these interfaces in constraints + // + // Likewise, even complex numbers have an absolute value but its always a real number. We therefore moveed this down to + // `INumberBase`. The downside is it removes the ability to give it a default implementation since its no longer simply + // checking if the value is negative and inversing it. + + static abstract TSelf Abs(TSelf value); + // { + // // Provided as an example of the DIM implementation for `INumber` types + // + // if (IsNegative(value)) + // { + // return checked(-value); + // } + // return value; + // } + // Alias for MultiplicativeIdentity static abstract TSelf One { get; } @@ -1491,6 +1426,89 @@ namespace System.Numerics static abstract bool IsZero(TSelf value); + // Much like with Abs, since the comparison works over the absolute value this is well-defined for + // complex numbers and can be provided on `INumberBase` + + static abstract TSelf MaxMagnitude(TSelf x, TSelf y); + // { + // // Provided as an example of the DIM implementation for `INumber` types + // + // TSelf ax = Abs(x); + // TSelf ay = Abs(y); + // + // if ((ax > ay) || IsNaN(ax)) + // { + // return x; + // } + // + // if (ax == ay) + // { + // return IsNegative(x) ? y : x; + // } + // + // return y; + // } + + static abstract TSelf MaxMagnitudeNumber(TSelf x, TSelf y) + // { + // // Provided as an example of the DIM implementation for `INumber` types + // + // TSelf ax = Abs(x); + // TSelf ay = Abs(y); + // + // if ((ax > ay) || IsNaN(ay)) + // { + // return x; + // } + // + // if (ax == ay) + // { + // return IsNegative(x) ? y : x; + // } + // + // return y; + // } + + static abtract TSelf MinMagnitude(TSelf x, TSelf y) + // { + // // Provided as an example of the DIM implementation for `INumber` types + // + // TSelf ax = Abs(x); + // TSelf ay = Abs(y); + // + // if ((ax < ay) || IsNaN(ax)) + // { + // return x; + // } + // + // if (ax == ay) + // { + // return IsNegative(x) ? x : y; + // } + // + // return y; + // } + + static abstract TSelf MinMagnitudeNumber(TSelf x, TSelf y) + // { + // // Provided as an example of the DIM implementation for `INumber` types + // + // TSelf ax = Abs(x); + // TSelf ay = Abs(y); + // + // if ((ax < ay) || IsNaN(ay)) + // { + // return x; + // } + // + // if (ax == ay) + // { + // return IsNegative(x) ? x : y; + // } + // + // return y; + // } + protected static abstract bool TryConvertFromChecked(TOther value, out TSelf? result) where TOther : INumber; @@ -1704,16 +1722,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -1721,6 +1734,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -1739,6 +1753,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -1851,16 +1869,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing - Explicit // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // ? Explicit // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // ? Explicit @@ -1868,6 +1881,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -1886,6 +1900,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2139,16 +2157,11 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * Existing // * TSelf operator checked *(TSelf, TSelf) // ? Explicit // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing @@ -2156,6 +2169,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -2174,6 +2188,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2340,16 +2358,11 @@ namespace System // * TSelf Log10(TSelf) // * TSelf Log10P1(TSelf) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing @@ -2357,6 +2370,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -2375,6 +2389,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2575,16 +2593,11 @@ namespace System // * TSelf operator *(TSelf, TSelf) // * TSelf operator checked *(TSelf, TSelf) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing @@ -2592,6 +2605,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -2610,6 +2624,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2756,16 +2774,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -2773,6 +2786,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -2791,6 +2805,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -2906,16 +2924,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -2923,6 +2936,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -2941,6 +2955,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3056,16 +3074,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -3073,6 +3086,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3091,6 +3105,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3198,16 +3216,11 @@ namespace System // * IFormattable // * string ToString(string?, IFormatProvider?) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) @@ -3215,6 +3228,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3233,6 +3247,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3343,16 +3361,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -3360,6 +3373,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3378,6 +3392,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3493,16 +3511,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -3510,6 +3523,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3528,6 +3542,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3686,16 +3704,11 @@ namespace System // * TSelf Log10(TSelf) // * TSelf Log10P1(TSelf) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing @@ -3703,6 +3716,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3721,6 +3735,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * Existing // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -3962,16 +3980,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -3979,6 +3992,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -3997,6 +4011,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4109,16 +4127,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -4126,6 +4139,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4144,6 +4158,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4256,16 +4274,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -4273,6 +4286,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4291,6 +4305,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4397,16 +4415,11 @@ namespace System // * IFormattable // * string ToString(string?, IFormatProvider?) // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) @@ -4414,6 +4427,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4432,6 +4446,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4540,16 +4558,11 @@ namespace System // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args @@ -4557,6 +4570,7 @@ namespace System // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4575,6 +4589,10 @@ namespace System // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4729,16 +4747,11 @@ namespace System.Runtime.InteropServices // * IFormattable // * string ToString(string?, IFormatProvider?) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) @@ -4746,6 +4759,7 @@ namespace System.Runtime.InteropServices // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4764,6 +4778,10 @@ namespace System.Runtime.InteropServices // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -4869,16 +4887,11 @@ namespace System.Runtime.InteropServices // * IFormattable // * string ToString(string?, IFormatProvider?) // * INumber - // * TSelf Abs(TSelf) // ? Explicit // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // ? Explicit // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * TSelf MinNumber(TSelf, TSelf) // ? Explicit // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) @@ -4886,6 +4899,7 @@ namespace System.Runtime.InteropServices // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase + // * TSelf Abs(TSelf) // ? Explicit // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -4904,6 +4918,10 @@ namespace System.Runtime.InteropServices // * bool IsSignalingNaN(TSelf) // ? Explicit // * bool IsSubnormal(TSelf) // ? Explicit // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -5050,16 +5068,11 @@ namespace System.Runtime.InteropServices // * TSelf Log10(TSelf) // * TSelf Log10P1(TSelf) // * INumber - // * TSelf Abs(TSelf) // * TSelf Clamp(TSelf, TSelf, TSelf) // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * TSelf MinNumber(TSelf, TSelf) // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) @@ -5067,6 +5080,7 @@ namespace System.Runtime.InteropServices // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) @@ -5085,6 +5099,10 @@ namespace System.Runtime.InteropServices // * bool IsSignalingNaN(TSelf) // * bool IsSubnormal(TSelf) // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) From 8099e7c9e0dfc7b549d2de57656e782f9a88e56a Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 11:18:06 -0700 Subject: [PATCH 21/35] Adding some additional documentation/callouts on a couple considerations --- accepted/2021/statics-in-interfaces/README.md | 190 +++++++++++++++--- 1 file changed, 157 insertions(+), 33 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index d3d6d648c..5339b0af5 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -874,15 +874,39 @@ namespace System.Numerics // We might want to support "big multiplication" for fixed width types // This would return a tuple (TSelf high, TSelf low) or similar, to match what we do for System.Math - // Returning int is currently what BitOperations does, however this can be cumbersome or prohibitive - // in various algorithms where returning TSelf is better. - public static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) { TSelf quotient = left / right; return (quotient, (left - (quotient * right))); } + // For `LeadingZeroCount`, `PopCount`, and `TrailingZeroCount` `System.Numerics.BitOperations` + // returns `int` + // + // This may require the developer to insert additional conversions from `int` to `TSelf` + // which might be problematic in some scenarios. Likewise, when it comes to "BigInteger" + // like types, there is no guarantee that the "bit count" is actually limited to `int` + // + // Returning `long` would reasonably handle the bit count issue, but there issue of + // converting back to `TSelf` still exists as there may be perf implications or other + // issues with doing that conversion. + // + // This might still overall be acceptable and will need to be decided on by API review + // as the reverse consideration also exists. That is, returning `int` is "natural" to + // C# and .NET code, so returning `TSelf` (such as for `BigInteger`) might also cause + // additional and unnecessary code to execute. + // + // The `rotateAmount` and `shiftAmount` parameters have similar considerations. + // + // Finally, variable sized types may return different results on different platforms. + // Consider for example `nint`, `nuint`, `CLong`, and `CULong` where `LeadingZeroCount(5)` + // returns a different result based on if we're on a 32-bit or 64-bit system. A user + // could likewise implement `BigInteger` such that it is represented via a `nuint[]`. + // + // In order to support such scenarios, we define these operations to be in terms of + // `GetByteCount() * 8L` bits. This is sufficient to explain how both fixed and variable + // width types behave and keeps the result deterministic for a given run. + public static virtual TSelf LeadingZeroCount(TSelf value) { TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); @@ -912,6 +936,17 @@ namespace System.Numerics static abstract TSelf TrailingZeroCount(TSelf value); // These methods allow getting the underlying bytes that represent the binary integer + // + // There are two considerations for these APIs. The first is that a developer may only + // want a subset of the bits. For example, if converting a `BigInteger` to a `int`, then + // `GetShortestBitLength` + `IsNegative` lets you know if it should `throw` or `saturate`. + // + // The second consideration is that an API may contain more than `int.MaxValue` bytes, such + // as if it is backed by native memory. + // + // If we provided an API like `int WritePartialBytes(Span destination, int firstByte)` + // then we could get just the lowest `4-bytes` and make the overall conversion "much" cheaper + // while also allowing users to "chunk" particularly big data if that was appropriate. int GetByteCount(); @@ -972,9 +1007,6 @@ namespace System.Numerics // This interface is defined for convenience of viewing the IEEE requirements // it would not actually be defined until the .NET libraries requires it - // The majority of the IEEE required operations are listed below - // This doesn't include the recommended operations such as sin, cos, acos, etc - // 5.3.2 // TSelf Quantize(TSelf x, TSelf y); // TSelf Quantum(TSelf x); @@ -989,11 +1021,19 @@ namespace System.Numerics // bool SameQuantum(TSelf x, TSelf y); } + // `IFloatingPoint` doesn't cover all relevant concepts. It doesn't for example necessarily cover `IFixedPoint` + // nor does it cover types like `Rational` which don't "contain" any point. These types are more rare overall + // and so while it is somewhat unfortunate they aren't represented in the initially exposed interfaces, this + // might be acceptable. + public interface IFloatingPoint : INumber, ISignedNumber where TSelf : IFloatingPoint { + // Rounding APIs might apply to more kinds than just "floating-point" types. + // Its possible we should define `IRoundFunctions` to contain them. + static abstract TSelf Ceiling(TSelf x); static abstract TSelf Floor(TSelf x); @@ -1045,14 +1085,32 @@ namespace System.Numerics ITrigonometricFunctions where TSelf : IFloatingPointIeee754 { - // The following constants are defined by System.Math and System.MathF today + // The following members have named equivalents defined by System.Math, System.MathF, or + // the IEEE 754 floating-point types. Like with floating-point, some of the concepts might + // be more broadly applicable. While there are certainly types, like `decimal` that don't + // support them at the same time. + // + // This notably doesn't include anything covering the full subnormal or finite "boundaries". + // That is, there is while `Epsilon` covers the smallest subnormal magnitude and `MaxValue` + // covers the largest finite magnitude, there is nothing that covers the largest subnormal + // magnitude or the smallest finite magnitude. static abstract TSelf E { get; } + static abstract TSelf Epsilon { get; } + + static abstract TSelf NaN { get; } + + static abstract TSelf NegativeInfinity { get; } + + static abstract TSelf NegativeZero { get; } + static abstract TSelf Pi { get; } static abstract TSelf Tau { get; } + static abstract TSelf PositiveInfinity { get; } + // The following methods are defined by System.Math and System.MathF today // Exposing them on the interfaces means they will become available as statics on the primitive types // This, in a way, obsoletes Math/MathF and brings float/double inline with how non-primitive types support similar functionality @@ -1078,28 +1136,10 @@ namespace System.Numerics static abstract TSelf ScaleB(TSelf x, int n); - // The following members are exposed on the floating-point types as constants today - // This may be of concern when implementing the interface - - // TODO: We may want to expose constants related to the subnormal and finite boundaries - - static abstract TSelf Epsilon { get; } - - static abstract TSelf NaN { get; } - - static abstract TSelf NegativeInfinity { get; } - - static abstract TSelf NegativeZero { get; } - - static abstract TSelf PositiveInfinity { get; } - // The following methods are approved but not yet implemented in the libraries static abstract TSelf Compound(TSelf x, TSelf n); - // The majority of the IEEE required operations are listed below - // This doesn't include the recommended operations such as sin, cos, acos, etc - // TODO: There are a couple methods below not covered in the list above, we should // review these and determine if they should be implemented @@ -1111,6 +1151,8 @@ namespace System.Numerics // TowardPositive // TowardNegative // Exact + // + // These are covered by `Round(TSelf x, MidpointRounding mode)` // 5.4.1 // TInt ConvertToInteger(TSelf x); @@ -1124,10 +1166,17 @@ namespace System.Numerics // ExactTowardPositive // ExactTowardNegative // ExactTiesToAway + // + // These are minimally covered by the `Create` APIs. Likewise they are + // minimally covered under a two step rounding logic (`Round` + `Create`). + // + // A user can "emulate" `Exact` by checking `IsInteger` and throwing if false // 5.4.3 // TResult ConvertFromHexCharacter(string s); // string ConvertToHexCharacter(TSelf x, TFormat format); + // + // These are approved, but not yet implemented, as `ToString` and `Parse` // 5.6.1 // bool Compare(TSelf x, TSelf y); @@ -1153,17 +1202,47 @@ namespace System.Numerics // QuietNotLess // QuietGreaterUnordered // QuietOrdered + // + // We don't support signaling NaN, but these are mostly covered by `<`, `>`, + // `<=`, and `>=`. + // + // The `unordered` are meant to return `true` if either input is `NaN`, which + // we don't support directly. // 5.7.1 // bool Is754Version1985 // bool Is754Version2008 // bool Is754Version2019 + // + // This is a "static" query that could be exposed and implemented by the interface // 5.7.2 // enum Class(TSelf x); - // enum Radix(TSelf x); // bool TotalOrder(TSelf x, TSelf y); // bool TotalOrderMag(TSelf x, TSelf y); + // + // Class is supposed to return one of the following enumeration values + // signalingNaN + // quietNaN + // negativeInfinity + // negativeNormal + // negativeSubnormal + // negativeZero + // positiveZero + // positiveSubnormal + // positiveNormal + // positiveInfinity + // It is meant to be a more efficient way to check kind than querying many + // individual `Is*` methods. + // + // `TotalOrder` is similar to `IComparable.Compare` but as a static + // method. With `TotalOrderMag` doing the same but over the absolute values. + // + // There are some notable differences in that it returns `bool` not an integer + // and therefore doesn't check for equality, it only checks for `x < y`. However, + // it also treats `-0` as less than `+0`, not equal. It gives a well defined order + // for `NaN` as compared to other values (`-NaN` is lesser then everything and + // `+NaN` is greater than everything, including infinity). // 9.4 // TSelf Sum(TSelf[] x); @@ -1173,16 +1252,29 @@ namespace System.Numerics // (TSelf, TInt) ScaledProd(TSelf[] x); // (TSelf, TInt) ScaledProdSum(TSelf[] x, TSelf[] y); // (TSelf, TInt) ScaledProdDiff(TSelf[] x, TSelf[] y); + // + // These are reduction operations that operate over an array + // and so take in a `T[]` and return a `T` that approximates + // the result + // + // Scaled* return values `pr` and `sf` such that `ScaleB(pr, sf)` + // approximates the result // 9.5 // (TSelf, TSelf) AugmentedAddition(TSelf x, TSelf y); // (TSelf, TSelf) AugmentedSubtraction(TSelf x, TSelf y); // (TSelf, TSelf) AugmentedMultiplication(TSelf x, TSelf y); + // + // These methods perform the operation as if `roundTiesTowardZero` + // was active and returns both the correctly rounded result and + // the error caused by the rounding. // 9.7 // TSelf GetPayload(TSelf x); // TSelf SetPayload(TSelf x); // TSelf SetPayloadSignaling(TSelf x); + // + // These methods allow getting and setting the payload bits of a NaN } public interface INumber @@ -1207,6 +1299,9 @@ namespace System.Numerics return result; } + // CopySign could theoretically move down since it is merely copying the signs + // from one value to the sign of another value. + public static TSelf CopySign(TSelf value, TSelf sign) { TSelf result = value; @@ -1219,6 +1314,9 @@ namespace System.Numerics return result; } + // `Max`, `MaxNumber`, `Min`, and `MinNumber` are only valid when there + // is a well defined order. + public static virtual TSelf Max(TSelf x, TSelf y) { if (val1 != val2) @@ -1274,12 +1372,22 @@ namespace System.Numerics return IsNegative(x) ? x : y; } + // Parse could move down. There are some potential complexities in supporting parsing for types like + // `Complex`, however; and so we need to determine if that is desirable. + static abstract TSelf Parse(string s, NumberStyles style, IFormatProvider? provider); static abstract TSelf Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider); + static abstract bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out TSelf result); + + static abstract bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out TSelf result); + // Math only exposes this Sign for signed types, but it is well-defined for unsigned types // it can simply never return -1 and only 0 or 1 instead + // + // It likely doesn't make sense for `Complex` because there isn't a single sign available and + // so the sign of imaginary numbers isn't well-defined. public static virtual int Sign(TSelf value) { @@ -1290,10 +1398,6 @@ namespace System.Numerics return 0; } - - static abstract bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out TSelf result); - - static abstract bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out TSelf result); } public interface INumberBase @@ -1311,9 +1415,6 @@ namespace System.Numerics IUnaryNegationOperators where TSelf : INumberBase { - // There is an open question on whether properties like IsSigned, IsBinary, IsFixedWidth, Base/Radix, and others are beneficial - // We could expose them for trivial checks or users could be required to check for the corresponding correct interfaces - // Abs mirrors Math.Abs and returns the same type. This can fail for MinValue of signed integer types // // Swift has an associated type that can be used here, which would require an additional type parameter in .NET @@ -1396,6 +1497,29 @@ namespace System.Numerics throw new NotSupportedException(); } + // The various `Is*` checks are fairly critical in writing generic algorithms as they are the only + // way to detect various edge cases today. Many of these will be implemented returning a constant + // true/false on the derived type and will be only available via a constrained generic. + // + // `IsCanonical` largely only makes sense for `decimal` like types where there are multiple ways + // to represent the "same" value. + // + // `IsEvenInteger` and `IsOddInteger` check that the value is even or odd. The `Integer` in the name + // is to help clarify that `2.4` returns `false` for both, while `IsEvenInteger` would return `true` + // for `2.0`. + // + // `IsNegative` nor `IsPositive` have "well-defined" behavior for complex numbers and so they may both + // return false. + // + // `IsZero` checks for both positive and negative zero + // + // Some APIs which we should likely also include are: + // * static abstract bool IsComplexNumber(TSelf value); + // * static abstract bool IsRealNumber(TSelf value); + // + // There may also be a reason to check for `IsFixedWith` or `IsSigned`, while whether its binary or + // decimal is exposed via `Radix`. + static abstract bool IsCanonical(TSelf value); static abstract bool IsEvenInteger(TSelf value); From c07c9180e0d18ebe7549b144c447ac45e60c0136 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 14:05:30 -0700 Subject: [PATCH 22/35] Updating some additional docs around BigInteger, Complex, and the vector types --- accepted/2021/statics-in-interfaces/README.md | 512 +++++++++++++----- 1 file changed, 365 insertions(+), 147 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 5339b0af5..d310c8874 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -219,7 +219,6 @@ interface "ITrigonometricFunctions" interface "IUnaryNegationOperators" interface "IUnaryPlusOperators" interface "IUnsignedNumber" -interface "IVector" "IBinaryNumber" <|-- "IBinaryFloatingPointIeee754" "IFloatingPointIeee754" <|-- "IBinaryFloatingPointIeee754" @@ -269,20 +268,6 @@ interface "IVector" "IParsable" <|-- "ISpanParsable" -"IAdditionOperators" <|-- "IVector" -"IAdditiveIdentity" <|-- "IVector" -"IBitwiseOperators" <|-- "IVector" -"IComparisonOperators" <|-- "IVector" -"IDecrementOperators" <|-- "IVector" -"IDivisionOperators" <|-- "IVector" -"IIncrementOperators" <|-- "IVector" -"IModulusOperators" <|-- "IVector" -"IMultiplicativeIdentity" <|-- "IVector" -"IMultiplyOperators" <|-- "IVector" -"ISpanFormattable" <|-- "IVector" -"ISubtractionOperators" <|-- "IVector" -"IUnaryNegationOperators" <|-- "IVector" - class "BigInteger" class "Byte" class "Char" @@ -313,13 +298,6 @@ class "UInt64" class "UInt128" class "UIntPtr" class "ValueType" -class "Vector" -class "Vector64" -class "Vector128" -class "Vector256" -class "Vector2" -class "Vector3" -class "Vector4" "IBinaryInteger" <|-- "BigInteger" "ISignedNumber" <|-- "BigInteger" @@ -349,16 +327,9 @@ class "Vector4" "IAdditionOperators" <|-- "Complex" "IDivisionOperators" <|-- "Complex" -"IDivisionOperators" <|-- "Complex" -"IFormattable" <|-- "Complex" -"IExponentialFunctions" <|-- "Complex" -"IHyperbolicFunctions" <|-- "Complex" -"ILogarithmicFunctions" <|-- "Complex" "IMultiplyOperators" <|-- "Complex" "INumberBase" <|-- "Complex" -"IPowerFunctions" <|-- "Complex" -"IRootFunctions" <|-- "Complex" -"ITrigonometricFunctions" <|-- "Complex" +"ISignedNumber" <|-- "Complex" "ISubtractionOperators" <|-- "Complex" "ValueType" <|-- "Complex" @@ -514,20 +485,10 @@ class "Vector4" "ValueType" <|-- "UIntPtr" "Object" <|-- "ValueType" - -"IVector" <|-- "Vector" - -"IVector" <|-- "Vector64" -"IVector" <|-- "Vector128" -"IVector" <|-- "Vector256" - -"IVector" <|-- "Vector2" -"IVector" <|-- "Vector3" -"IVector" <|-- "Vector4" @enduml --> -![UML](http://www.plantuml.com/plantuml/svg/h9XBKzi-4C3l_XIPdFySU91_3mpJyg1ufZGPd73VE1j7hIobaWouqm_V6AY29MUZAEJ2x7hrq-gn3_5P6r2cAdd2X44rXnnx_VHIbajGCENOtw0_6v-xdyGZAiEyCLUeKJ7Wx3SO9iKbS3w5_6VRwFfN1QQJUoDL2SRulen0wTSH6VAvCofxcz8VbYr1ECpsHu_RilWocx5c6SCbAZ1IwLUp_thZeLcWMlszHrrninhd3tl4T8R2C5FRKPtM5qo0gc-u1CD4CP9Cc1GH_pyziKxvvkbAKw0YBBvNvNIZWNbY6eDMvLu7fZTkXsD_XRd24eLnp5qpziXqs1wxTuWpKuVvSlsybA8v3E0tbSYRC-tsfdKCX4N0GTtMIrHJoLbEJvcAe7tw9WjGp2pARRmx9kxW-G5uXTtVvQpYbTvnl-zMAhRaB8VGcst7r3jEvTrSzzC5wEwbZUGJAdftxgKqj4MsO7EpeyiPAmJE2CUpQceKv179PAnO8OKiqQXj9pzvYNiie7CQ7s_7Z7YbW-trjhK-OBxYM4oM0mVLfDRkrDJR-3lxSt0GbY3fi8mdnplTdQQ3RrS8BDaXa_iqvm3TiEkHFvgLj7eAccDXWHN6RKi-41rGL6BHYTFq1Er8K9MBFRZkGjUToI9X2Lrt2Lfuf3kmM2PHgwEPLC6EPNONkFtMxbV4_VUJBbenp2Geq7oeb-R2-qs24jv44RwuxGonxnJ5VUIG39hYlePsfIIxF9aSZDFM1RoYh3CqYNY9M4G8AQ904AHKV8nFmPrvEAdUz-nsR7S9Kb1_6hHFmTtnLj8A5Hvj5kM7QGEY0uu0kGFZGezercFYZy15jAe4Bg8O4BZe547W8eeCWKl5XtaNKRm8N4G22iNL--zTJ7KaS36PZS159YK2b-GSjExrBrZnzbRiMrLjq0gN2rX_QGA9uxELhy3WKF2wfHYp4Zt5S3xNQDPgp5a9V2tBQihNewv5LLhXQyLcLhW5FhT2AipXuBrqVFHU6foybqP6MN4u_O6viMBMMd76HC7NOkDzSo-iOjAUTjAUTzAUUEBC_FAljd6zNFF_7T2vencS-Bh3eq--ykXqqA5qv6D7_bki7Tmq40DX6BrlEIJYJ0-83k06tEWV2Mdq4SGYw_b00S-mVoRExDZNfXND2fRQ-Gf6Nm6_hr0Wjsnz1NgCAVARqud8elrbUhfepsPZ2nOYor9Oimb0M5a8AmjXZOMmnbgRr2RPJ_i_SEeyupAFYTEO94uJaJWs1d5usOxJw2LEKvOu3LJYrBN4yViMfsQzFiJscRprW7cRZUGjlpplMVLjz2wNzmym3pyoUIo0_EqD0VZxMa1vAg0yV7_pKe3vhGBiFM6t35l5Yx5LJc-gH9V-5o_CLl7oR9NT8cqLBzLMyO9jbRsoRHNRVNgRnKg9otbLt2eiBgKLbqyWVgoSiF_q3GxiWqj3ScbuyZGTWC-8H1uxEni0M7ZaiRGhpnX8Tgwni5-DXGVEKcdFg0jACml_z5YQ5Cn83keo38ySXf5KM08BUsANEqWi38c58R4m9HRsnEwla5WO4Wj3Oc58B8o9DVwMfqx3OwUXlKXBQccExH67n668F0o9XocoCFrcTNO2aQKjipGyTngxaw-t29z0vR73oLkNavVtiRp6dyS1GiTqDZh8Qm7aPMwVvmBAmo5xteRdUI_WF1LmNWeu3mVjURs7bBSlK1v_x9wyTKzByQRXf2zjmQKzDkpVqnPRscFJ5ZxjiM4JdxROqXwRzl5fZyqx-RWrut5Fpflv-37tTrPilZzw7AVtelvUeQiwla9NUto9RWBv6bqSsbjaxt-u8EyQqyFB-_F7s-id) +![UML](http://www.plantuml.com/plantuml/svg/h9ZFKjiy4C3lVefCpd3u-2ZjWUcq12YP0PB1SU-Ait5KPCcLLe0xVVWcWR6mx2Xh1oxCIgkVzu-YNUcRGQRHvYBY4a4lMGg3uNYaye9fDXSmt35-FllgJyadqCWRQox1WEPCy3yCkP8Z9iISfOzrfQlVbc4hzrhfd24sRPaoRLvNn22MtghuxPFDPN71fC-iJJQuDOtlYmNVk34fG3DKshog7Grc4ro1Nlz_06C5hjSrbpt1U04IEPRLgbRj2owPBg-5OiXbDbLSuXW0FdywTSusrCSI8GCTqBYt-Nod0Zvp0oIl_Et0pSvmUFgNa6h8GQAdxgln9sveCVRtaE1OqcovUYcKt2I3YMihqqrEswsffI6WGKZKJLc0dYl1q_0dnv8KfrkLCSrnbU_ZtN5vnrv-Cc6XVLujhB2cOxplraEy43nbn9tjrfGTF-NjtERK1JCGc7uxd3Q8eq4ILXcj87s41K4pPcZrDlC4vPcsCjsfF5NFeCD9V50AmnhnYY-nOsHZdabO1E8RspbgblOuysQQPqgg753lsw39zdY2ZBL_niUxDLDX3LdVjFaQjP-EWvr_vt-FZsbdTFXaw4i-t6Y_Kf1t3WKMTIWcFittPysYEZZOoufgRKqGus348kTtHX-89jIrlkZ8wxj84I4Lshw9Qw-rxQTKJrWKBlq16lsNxiDwCOFjGazck6VeosmlNeVvtgnsXySpN93wC2FI3wq9RHnpz9OtGA7tSG5R_8ug4FSGnRzd1HbXYdyXwqg9kjpQF8pNMH8kSiwQ82bm6N880ebK8CYaiVmecuYN0pgfF3ntdLhP08dKUvBYHEvyzvBMAFglpQ6Qpo5HysM536e-dQI26JCONl3ihKySLaCbGYMCLamxuLR9p4agBmIyE3cfJLyoX8aKPMrWndDe34oMImFeXY7bEHDELdOktAehQVDA-67veX9kc5XMmbZYVsVlfVzFtajdfpNDao_lnIawd--tPQOI9_DVa3enhWKhvZ8JJjpujWb-DP3KZKhgLYLrinBFhiGpRFjeC2kBpSxmMdvYLNQvftTo0O8poDEb4VgxiKr1_PsJ_Fb_fTf1gkf048RHULRb7YGxq9awS_z2u818XEQh1Pn-h_zR9btLEUpf76RPdhUlIpP4nhQm_8JRZk6qPRZi6KwRzX0B5SA6lDWI5rlIOdjOUoyHEc-QJjkcux7I-yoXltC7eyZBCH-FXocy9e_7jijPeLOTNziRlZOsVCsFpxNhA1KQ8PvFVq2-FcNvNW3ypmrZ-FTh0V6rWFZo--Lh0VB30dIMdvQXLMR5Q9N_DzqBaLXbL9XMcPMdLMP5QfLPgLfbLh1McPQjLThJHySPAmMFmsOyLXWUImlFVm5yMxaUOtdDVNjjq2qvkkwSJhTNnXXjswm7GB1XosnwAXlLX2SN6vvNRDam6qlRE2gK9Xl-qspi_epDIbt2QSjm6aJ1AJ0u9cQqM1A3Ss9mIGmkYS4jCUFNc1YS4eDBOd1938w96GNNoEYM6Pr2erDgT8pDnBnkd8uRfyEfZ6wnqUd5vSgZLXlTGgVBnkbSBzT-bG2NRSEnrE0G6PnBnOrNZ8nkcT5fttGypHvTPvzOydbYoTTJCL_xTxx6p-U1aylLEchYwv29hzS5V2yWldtImTVx2huMCDyBcEy5p9TFFVZwqGdVVq1yVDdjlTMZSwz7jrj2kWL7zzXwlqVdsEWQMs_vw1vRR_he71jTO-jz7zrZctH-U0yEhydrvW_lsVNs3-yT7Dwpmrjs-EQBjINCVtzSThc_Rk_dumC0) ### Base Interfaces @@ -750,6 +711,9 @@ namespace System.Numerics { // These could have DIM implementations if they inherit // IPowerFunctions and had access to the constant `E` + // + // Several of these are reserved by the current C standard + // for future implementation on `complex` static abstract TSelf Exp(TSelf x); @@ -783,6 +747,9 @@ namespace System.Numerics public interface ILogarithmicFunctions where TSelf : ILogarithmicFunctions, INumberBase { + // Several of these are reserved by the current C standard + // for future implementation on `complex` + static abstract TSelf Log(TSelf x); static abstract TSelf Log(TSelf x, TSelf newBase); // ? DIM - Needs special floating-point handling for NaN, One, and Zero @@ -821,6 +788,12 @@ namespace System.Numerics public interface ITrigonometricFunctions where TSelf : ITrigonometricFunctions, INumberBase { + // `Atan2` and `Atan2Pi` aren't commonly defined for `complex` + // but they do represent the `phase` or `angle` of `x + iy` + // + // The `*Pi` APIs are reserved by the current C standard + // for future implementation on `complex` + static abstract TSelf Acos(TSelf x); static abstract TSelf Asin(TSelf x); @@ -1676,71 +1649,6 @@ namespace System.Numerics static abstract T Convert(U value); } } - -namespace System.Numerics -{ - public interface IVector - : IAdditionOperators, - IAdditiveIdentity, - IBitwiseOperators, - IComparisonOperators, // implies IEqualityOperators - IDivisionOperators, - IDivisionOperators, - IMultiplyOperators, - IMultiplicativeIdentity, - IMultiplicativeIdentity, - IMultiplyOperators, - IUnaryNegationOperators, - ISpanFormattable, // implies IFormattable - ISubtractionOperators - where TSelf : IVector - { - static abstract TSelf Create(TScalar value); - static abstract TSelf Create(TScalar[] values); - static abstract TSelf Create(TScalar[] values, int startIndex); - static abstract TSelf Create(ReadOnlySpan values); - - static abstract int Count { get; } - - static abstract TSelf One { get; } - - static abstract TSelf Zero { get; } - - TScalar this[int index] { get; } - - static abstract TSelf Abs(TSelf value); - static abstract TSelf AndNot(TSelf left, TSelf right); - static abstract TSelf ConditionalSelect(TSelf condition, TSelf left, TSelf right); - static abstract TSelf Dot(TSelf left, TSelf right); - static abstract TSelf Max(TSelf left, TSelf right); - static abstract TSelf Min(TSelf left, TSelf right); - static abstract TSelf SquareRoot(TSelf value); - - static abstract TSelf Equals(TSelf left, TSelf right); - static abstract TSelf GreaterThan(TSelf left, TSelf right); - static abstract TSelf GreaterThanOrEqual(TSelf left, TSelf right); - static abstract TSelf LessThan(TSelf left, TSelf right); - static abstract TSelf LessThanOrEqual(TSelf left, TSelf right); - - static abstract bool EqualsAll(TSelf left, TSelf right); - static abstract bool GreaterThanAll(TSelf left, TSelf right); - static abstract bool GreaterThanOrEqualAll(TSelf left, TSelf right); - static abstract bool LessThanAll(TSelf left, TSelf right); - static abstract bool LessThanOrEqualAll(TSelf left, TSelf right); - - static abstract bool EqualsAny(TSelf left, TSelf right); - static abstract bool GreaterThanAny(TSelf left, TSelf right); - static abstract bool GreaterThanOrEqualAny(TSelf left, TSelf right); - static abstract bool LessThanAny(TSelf left, TSelf right); - static abstract bool LessThanOrEqualAny(TSelf left, TSelf right); - - void CopyTo(TScalar[] destination); - void CopyTo(TScalar[] destination, int startIndex); - void CopyTo(Span destination); - - bool TryCopyTo(Span destination); - } -} ``` ### Interface Implementors @@ -4738,43 +4646,227 @@ namespace System.Numerics { public struct BigInteger : IBinaryInteger, - ISignedNumber, - ISpanFormattable, - ISpanParsable + ISignedNumber { + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IBitwiseOperators + // * TSelf operator &(TSelf, TSelf) + // * TSelf operator |(TSelf, TSelf) + // * TSelf operator ^(TSelf, TSelf) + // * TSelf operator ~(TSelf) + // * IComparisonOperators + // * bool operator <(TSelf, TSelf) + // * bool operator <=(TSelf, TSelf) + // * bool operator >(TSelf, TSelf) + // * bool operator >=(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) + // * bool operator !=(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IModulusOperators + // * TSelf operator %(TSelf, TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * IShiftOperators + // * TSelf operator <<(TSelf, TSelf) + // * TSelf operator >>(TSelf, TSelf) + // * TSelf operator >>>(TSelf, TSelf) + // * TSelf operator <<(TSelf, int) + // * TSelf operator >>(TSelf, int) + // * TSelf operator >>>(TSelf, int) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) + + // Implicitly Implemented interfaces + + // * INumberBase + // * One { get; } // * Existing + // * Zero { get; } // * Existing + // * ISignedNumber + // * TSelf NegativeOne { get; } // BigInteger exposes `BigInteger MinusOne { get; }` + // + // * IBinaryInteger + // * (TSelf, TSelf) DivRem(TSelf, TSelf) + // * int GetByteCount() // ? Explicit - BigInteger exposes `int GetByteCount(bool isUnsigned = false)` + // * long GetShortestBitLength() // ? Explicit - BigInteger exposes `long GetBitLength()` + // * TSelf LeadingZeroCount(TSelf) + // * TSelf PopCount(TSelf) + // * TSelf RotateLeft(TSelf, int) + // * TSelf RotateRight(TSelf, int) + // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit - BigInteger exposes `bool TryWriteBytes(Span destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false)` + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit + // * IBinaryNumber + // * bool IsPow2(TSelf) // BigInteger expoes `bool IsPowerOfTwo { get; }` + // * TSelf Log2(TSelf) + // * IComparable // Existing + // * int CompareTo(object?) // * Existing + // * int CompareTo(TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing + // * IFormattable // Existing + // * string ToString(string?, IFormatProvider?) // * Existing + // * INumber + // * TSelf Clamp(TSelf, TSelf, TSelf) + // * TSelf CopySign(TSelf, TSelf) + // * TSelf Max(TSelf, TSelf) + // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit + // * TSelf Min(TSelf, TSelf) + // * TSelf MinNumber(TSelf, TSelf) // ? Explicit + // * TSelf Parse(string, NumberStyles, IFormatProvider?) // * Existing + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * Existing - Optional Args + // * int Sign(TSelf) // BigInteger exposes `int Sign { get; }` + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * Existing + // * INumberBase + // * TSelf Abs(TSelf) + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) + // * bool IsEvenInteger(TSelf) // BigInteger exposes `bool IsEven { get; }` + // * bool IsFinite(TSelf) // ? Explicit + // * bool IsInfinity(TSelf) // ? Explicit + // * bool IsInteger(TSelf) // ? Explicit + // * bool IsNaN(TSelf) // ? Explicit + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) // ? Explicit + // * bool IsNormal(TSelf) // ? Explicit + // * bool IsOddInteger(TSelf) + // // BigInteger exposes `bool IsOne { get; }` + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // ? Explicit + // * bool IsSignalingNaN(TSelf) // ? Explicit + // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsZero(TSelf) // BigInteger exposes `bool IsZero { get; }` + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) + // * IParsable + // * TSelf Parse(string, IFormatProvider?) // * Existing + // * bool TryParse(string?, IFormatProvider?, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) // * Existing - Optional Args + // * ISpanParsable + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) } public struct Complex : IAdditionOperators, - IDivisionOperators, IDivisionOperators, - IFormattable, - // IExponentialFunctions, - // IHyperbolicFunctions, - // ILogarithmicFunctions, IMultiplyOperators, INumberBase, - // IPowerFunctions - // IRootFunctions, - // ITrigonometricFunctions, + ISignedNumber, ISubtractionOperators { - } - - public struct Vector : IVector, T> - { - } - - public struct Vector2 : IVector - { - } - - public struct Vector3 : IVector - { - } + // Explicitly implemented interfaces + // * IAdditiveIdentity + // * TSelf AdditiveIdentity { get; } + // * IMultiplicativeIdentity + // * TSelf MultiplicativeIdentity { get; } + // * INumberBase + // * TSelf One { get; } + // * TSelf Zero { get; } + // * ISignedNumber + // * TSelf NegativeOne { get; } + // + // * IAdditionOperators + // * TSelf operator +(TSelf, TSelf) + // * TSelf operator checked +(TSelf, TSelf) + // * IDecrementOperators + // * TSelf operator --(TSelf) + // * TSelf operator checked --(TSelf) + // * IDivisionOperators + // * TSelf operator /(TSelf, TSelf) + // * TSelf operator checked /(TSelf, TSelf) + // * IIncrementOperators + // * TSelf operator ++(TSelf) + // * TSelf operator checked ++(TSelf) + // * IMultiplyOperators + // * TSelf operator *(TSelf, TSelf) + // * TSelf operator checked *(TSelf, TSelf) + // * ISubtractionOperators + // * TSelf operator -(TSelf, TSelf) + // * TSelf operator checked -(TSelf, TSelf) + // * IUnaryNegationOperators + // * TSelf operator -(TSelf) + // * TSelf operator checked -(TSelf) + // * IUnaryPlusOperators + // * TSelf operator +(TSelf) - public struct Vector4 : IVector - { + // Implicitly implemented interfaces + // * IEqualityOperators + // * bool operator ==(TSelf, TSelf) // * Existing + // * bool operator !=(TSelf, TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing + // * IFormattable // Existing + // * string ToString(string?, IFormatProvider?) // * Existing + // * INumberBase + // * TSelf Abs(TSelf) + // * TSelf CreateChecked(TOther) + // * TSelf CreateSaturating(TOther) + // * TSelf CreateTruncating(TOther) + // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsEvenInteger(TSelf) + // * bool IsFinite(TSelf) // * Existing + // * bool IsInfinity(TSelf) // * Existing + // * bool IsInteger(TSelf) + // * bool IsNaN(TSelf) // * Existing + // * bool IsNegative(TSelf) // * Existing + // * bool IsNegativeInfinity(TSelf) // * Existing + // * bool IsNormal(TSelf) // * Existing + // * bool IsOddInteger(TSelf) + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) // * Existing + // * bool IsSignalingNaN(TSelf) + // * bool IsSubnormal(TSelf) // * Existing + // * bool IsZero(TSelf) + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) + // * bool TryConvertFromChecked(TOther, out TSelf) + // * bool TryConvertFromSaturating(TOther, out TSelf) + // * bool TryConvertFromTruncating(TOther, out TSelf) + // * bool TryConvertToChecked(TOther, out TSelf) + // * bool TryConvertToSaturating(TOther, out TSelf) + // * bool TryConvertToTruncating(TOther, out TSelf) + // * ISpanFormattable + // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) // * Existing } } @@ -5266,21 +5358,6 @@ namespace System.Runtime.InteropServices // * TSelf TanPi(TSelf) // Approved - NYI } } - -namespace System.Runtime.Intrinsics -{ - public struct Vector64 : IVector, T> - { - } - - public struct Vector128 : IVector, T> - { - } - - public struct Vector256 : IVector, T> - { - } -} ``` ### Create and Conversion APIs explained @@ -5661,6 +5738,147 @@ This leaves us with the `TryConvertFrom`/`TryConvertTo` pattern for the majority We could expose these, but they have the same general limitations as the `Create` APIs. Additionally, it vastly increases the number of interfaces implemented since there are 11 primitive integer types (`byte`, `char`, `short`, `int`, `long`, `nint`, `sbyte`, `ushort`, `uint`, `ulong`, and `nuint`), 3 primitive floating-point types (`decimal`, `double`, and `float`), and some 6 other ABI primitive types (`Half`, `Int128`, `UInt128`, `NFloat`, `CLong`, and `CULong`). Supporting single-direction conversions for these requires at least 14 interfaces. Bi-directional doubles that to 24. +### Future Considerations + +``` +namespace System.Numerics +{ + // IComplex and IVector would be nice to have but are not strictly required for .NET 7 + + public interface IComplex + : IAdditionOperators, + IDivisionOperators, + IExponentialFunctions, + IHyperbolicFunctions, + ILogarithmicFunctions, + IMultiplyOperators, + INumberBase, + IPowerFunctions, + IRootFunctions, + ISubtractionOperators, + ITrigonometricFunctions + { + static abstract TScalar Imaginary { get; } + + static abstract TScalar Magnitude { get; } + + static abstract TScalar Phase { get; } + + static abstract TScalar Real { get; } + + new static abstract TScalar Abs(TSelf value); + + static abstract TSelf Conjugate(TSelf value); + + static abstract TSelf FromPolarCoordinates(TScalar magnitude, TScalar phase); + + static abstract TSelf Log(TSelf x, TScalar newBase); + + static abstract TSelf Pow(TSelf x, TScalar y); + + static abstract TSelf Reciprocal(TSelf value); + } + + public interface IVector + : IAdditionOperators, + IAdditiveIdentity, + IBitwiseOperators, + IComparisonOperators, // implies IEqualityOperators + IDivisionOperators, + IDivisionOperators, + IMultiplyOperators, + IMultiplicativeIdentity, + IMultiplicativeIdentity, + IMultiplyOperators, + IUnaryNegationOperators, + ISpanFormattable, // implies IFormattable + ISubtractionOperators + where TSelf : IVector + { + static abstract TSelf Create(TScalar value); + static abstract TSelf Create(TScalar[] values); + static abstract TSelf Create(TScalar[] values, int startIndex); + static abstract TSelf Create(ReadOnlySpan values); + + static abstract TSelf AllBitsSet { get; } + + static abstract int Count { get; } + + static abstract TSelf One { get; } + + static abstract TSelf Zero { get; } + + TScalar this[int index] { get; } + + static abstract TSelf Abs(TSelf value); + static abstract TSelf AndNot(TSelf left, TSelf right); + static abstract TSelf ConditionalSelect(TSelf condition, TSelf left, TSelf right); + static abstract TSelf Dot(TSelf left, TSelf right); + static abstract TSelf Max(TSelf left, TSelf right); + static abstract TSelf Min(TSelf left, TSelf right); + static abstract TSelf Sqrt(TSelf value); + + static abstract TSelf Equals(TSelf left, TSelf right); + static abstract TSelf GreaterThan(TSelf left, TSelf right); + static abstract TSelf GreaterThanOrEqual(TSelf left, TSelf right); + static abstract TSelf LessThan(TSelf left, TSelf right); + static abstract TSelf LessThanOrEqual(TSelf left, TSelf right); + + static abstract bool EqualsAll(TSelf left, TSelf right); + static abstract bool GreaterThanAll(TSelf left, TSelf right); + static abstract bool GreaterThanOrEqualAll(TSelf left, TSelf right); + static abstract bool LessThanAll(TSelf left, TSelf right); + static abstract bool LessThanOrEqualAll(TSelf left, TSelf right); + + static abstract bool EqualsAny(TSelf left, TSelf right); + static abstract bool GreaterThanAny(TSelf left, TSelf right); + static abstract bool GreaterThanOrEqualAny(TSelf left, TSelf right); + static abstract bool LessThanAny(TSelf left, TSelf right); + static abstract bool LessThanOrEqualAny(TSelf left, TSelf right); + + void CopyTo(TScalar[] destination); + void CopyTo(TScalar[] destination, int startIndex); + void CopyTo(Span destination); + + bool TryCopyTo(Span destination); + } +} + +namespace System.Numerics +{ + public struct Vector : IVector, T> + { + } + + public struct Vector2 : IVector + { + } + + public struct Vector3 : IVector + { + } + + public struct Vector4 : IVector + { + } +} + +namespace System.Runtime.Intrinsics +{ + public struct Vector64 : IVector, T> + { + } + + public struct Vector128 : IVector, T> + { + } + + public struct Vector256 : IVector, T> + { + } +} +``` + ### Pending Concepts There are several types which may benefit from some interface support. These include, but aren't limited to: From d9b63d9d4677c6f090339048b133e188df43f7c0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 14:06:03 -0700 Subject: [PATCH 23/35] Removing the draft label --- accepted/2021/statics-in-interfaces/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index d310c8874..0d831379f 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1,7 +1,5 @@ # Statics in Interfaces -**DRAFT** - **Owners** [Tanner Gooding](https://github.com/tannergooding) | [David Wrighton](https://github.com/davidwrighton) | [Mads Torgersen](https://github.com/MadsTorgersen) | [Immo Landwerth](https://github.com/terrajobst) C# is looking at enabling static abstract members in interfaces (https://github.com/dotnet/csharplang/issues/4436). From the libraries perspective, this is an opportunity to enable "generic math" which could define a new baseline for how developers write algorithms in .NET. From 56deb1129bfc8c0ee5cb4c04f2db7b2622d7addb Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 14:10:03 -0700 Subject: [PATCH 24/35] Run update-index --- INDEX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INDEX.md b/INDEX.md index f793c4fae..0b64dbc5a 100644 --- a/INDEX.md +++ b/INDEX.md @@ -76,6 +76,7 @@ Use update-index to regenerate it: | 2021 | [Make `System.Drawing.Common` only supported on Windows](accepted/2021/system-drawing-win-only/system-drawing-win-only.md) | [Santiago Fernandez Madero](https://github.com/safern) | | 2021 | [Objective-C interoperability](accepted/2021/objectivec-interop.md) | [Aaron Robinson](https://github.com/AaronRobinsonMSFT) | | 2021 | [Preview Features](accepted/2021/preview-features/preview-features.md) | [Immo Landwerth](https://github.com/terrajobst) | +| 2021 | [Statics in Interfaces](accepted/2021/statics-in-interfaces/README.md) | [Tanner Gooding](https://github.com/tannergooding), [David Wrighton](https://github.com/davidwrighton), [Mads Torgersen](https://github.com/MadsTorgersen), [Immo Landwerth](https://github.com/terrajobst) | | 2021 | [Streamline Windows Forms application configuration and bootstrap](accepted/2021/winforms/streamline-application-bootstrap.md) | [Igor Velikorossov](https://github.com/RussKie) | | 2021 | [TFM for .NET nanoFramework](accepted/2021/nano-framework-tfm/nano-framework-tfm.md) | [Immo Landwerth](https://github.com/terrajobst), [Laurent Ellerbach](https://github.com/Ellerbach), [José Simões](https://github.com/josesimoes) | | 2021 | [Tracking Platform Dependencies](accepted/2021/platform-dependencies/platform-dependencies.md) | [Matt Thalman](https://github.com/mthalman) | @@ -87,7 +88,6 @@ Use update-index to regenerate it: |----|-----|------| | 2021 | [Flexible HTTP APIs](accepted/2021/flexible-http.md) | [Cory Nelson](https://github.com/scalablecory), [Geoff Kizer](https://github.com/geoffkizer) | | 2021 | [Improve UTF-8 support](accepted/2021/utf8/README.md) | [Immo Landwerth](https://github.com/terrajobst) | -| 2021 | [Statics in Interfaces](accepted/2021/statics-in-interfaces/README.md) | [Tanner Gooding](https://github.com/tannergooding), [David Wrighton](https://github.com/davidwrighton), [Mads Torgersen](https://github.com/MadsTorgersen), [Immo Landwerth](https://github.com/terrajobst) | ## Proposals From a1a1bf27bac4721c996996c7cfacbfa5ec08f46c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 8 May 2022 14:11:57 -0700 Subject: [PATCH 25/35] Expose IBinaryInteger.ReverseEndianness --- accepted/2021/statics-in-interfaces/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 0d831379f..dd5c883fa 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -892,6 +892,8 @@ namespace System.Numerics static abstract TSelf PopCount(TSelf value); + public static abstract TSelf ReverseEndianness(TSelf value); + public static virtual TSelf RotateLeft(TSelf value, TSelf rotateAmount) { TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); @@ -1734,6 +1736,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -1881,6 +1884,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // ? Explicit // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -2786,6 +2790,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -2936,6 +2941,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -3086,6 +3092,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -3228,6 +3235,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -3370,6 +3378,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -3523,6 +3532,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -3992,6 +4002,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4139,6 +4150,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4286,6 +4298,7 @@ namespace System // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4427,6 +4440,7 @@ namespace System // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4567,6 +4581,7 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4712,6 +4727,7 @@ namespace System.Numerics // * long GetShortestBitLength() // ? Explicit - BigInteger exposes `long GetBitLength()` // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -4940,6 +4956,7 @@ namespace System.Runtime.InteropServices // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) @@ -5080,6 +5097,7 @@ namespace System.Runtime.InteropServices // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) + // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) From 6eaf809704395a6424bfff05994b2c995ae33eec Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 9 May 2022 07:54:11 -0700 Subject: [PATCH 26/35] Fixing a couple grammatical errors --- accepted/2021/statics-in-interfaces/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index dd5c883fa..46f1004a1 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -107,7 +107,7 @@ Jeff copies this code into his project and is now able to calculate the standard After thinking over the possible implementations, Jeff realizes that the only reliable way to implement this in .NET 5 is to define an interface with instance methods that users must then implement on their own types or to hardcode a list of types in their own library. They do not believe this to be as reusable or maintainable as hoped. -Jeff learns that a future version of .NET will offer a new feature called static abstracts in interfaces. Such a feature will have the .NET Libraries expose a set of interfaces that allow Jeff to implement the desired method without requiring users types to take a dependency on types they declared. +Jeff learns that a future version of .NET will offer a new feature called static abstracts in interfaces. Such a feature will have the .NET Libraries expose a set of interfaces that allow Jeff to implement the desired method without requiring users' types to take a dependency on types they declared. The .NET Libraries are exposing interfaces such as (NOTE: simplified names/examples are given below): ```csharp @@ -490,7 +490,7 @@ class "ValueType" ### Base Interfaces -The base interfaces each describe one or more core operations that are used to build up the core interfaces listed later. In many cases, such as for addition, subtraction, multiplication, and division, there is only a single operator per interface. This split is important in order for them to be reusable against downstream types, like `DateTime` where addition does not imply subtraction or `Matrix` where multiplication does not imply division. These interfaces are not expected to be used by many users and instead primarily by developers looking at defining their own abstractions, as such we are not concerned with adding simplifying interfaces like `IAdditionOperators : IAdditionOperators`. Likewise, every interface added introduces increased size and startup overhead, so we need to strike a balance between expressiveness, exxtensibility, and cost. +The base interfaces each describe one or more core operations that are used to build up the core interfaces listed later. In many cases, such as for addition, subtraction, multiplication, and division, there is only a single operator per interface. This split is important in order for them to be reusable against downstream types, like `DateTime` where addition does not imply subtraction or `Matrix` where multiplication does not imply division. These interfaces are not expected to be used by many users and instead primarily by developers looking at defining their own abstractions, as such we are not concerned with adding simplifying interfaces like `IAdditionOperators : IAdditionOperators`. Likewise, every interface added introduces increased size and startup overhead, so we need to strike a balance between expressiveness, extensibility, and cost. Some of the code below assumes that https://github.com/dotnet/csharplang/issues/4665 is going to be accepted into the language. If it is not accepted or if the approved syntax differs, the declarations will need to be updated. @@ -555,7 +555,7 @@ namespace System.Numerics // Given this takes two generic parameters, we could simply call it IComparable // This inherits from IEqualityOperators as even though IComparable does not - // inherit from IEquatable, the <= and >= operators as well as CompareTo iTSelf imply equality + // inherit from IEquatable, the <= and >= operators as well as CompareTo itself imply equality static abstract bool operator <(TSelf left, TOther right); From 35e729083e02ef4905d98976bead5717309b805e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:29:10 -0700 Subject: [PATCH 27/35] Remove ReverseEndianness in favor of WriteBigEndian APIs --- accepted/2021/statics-in-interfaces/README.md | 186 +++++++++++++++--- 1 file changed, 158 insertions(+), 28 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 46f1004a1..34b525a88 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -892,8 +892,6 @@ namespace System.Numerics static abstract TSelf PopCount(TSelf value); - public static abstract TSelf ReverseEndianness(TSelf value); - public static virtual TSelf RotateLeft(TSelf value, TSelf rotateAmount) { TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); @@ -929,8 +927,37 @@ namespace System.Numerics return bitCount - long.CreateChecked(TSelf.LeadingZeroCount(this)); } + bool TryWriteBigEndian(Span destination, out int bytesWritten); + bool TryWriteLittleEndian(Span destination, out int bytesWritten); + int WriteBigEndian(byte[] destination) + { + if (!TryWriteBigEndian(destination, out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } + + int WriteBigEndian(byte[] destination, int startIndex) + { + if (!TryWriteBigEndian(destination.AsSpan(startIndex), out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } + + int WriteBigEndian(Span destination) + { + if (!TryWriteBigEndian(destination, out int bytesWritten)) + { + ThrowHelper.ThrowArgumentException_DestinationTooShort(); + } + return bytesWritten; + } + int WriteLittleEndian(byte[] destination) { if (!TryWriteLittleEndian(destination, out int bytesWritten)) @@ -1031,16 +1058,32 @@ namespace System.Numerics int GetSignificandByteCount(); + bool TryWriteExponentBigEndian(Span destination, out int bytesWritten); + bool TryWriteExponentLittleEndian(Span destination, out int bytesWritten); + bool TryWriteSignificandBigEndian(Span destination, out int bytesWritten); + bool TryWriteSignificandLittleEndian(Span destination, out int bytesWritten); + int WriteExponentBigEndian(byte[] destination); + + int WriteExponentBigEndian(byte[] destination, int startIndex); + + int WriteExponentBigEndian(Span destination); + int WriteExponentLittleEndian(byte[] destination); int WriteExponentLittleEndian(byte[] destination, int startIndex); int WriteExponentLittleEndian(Span destination); + int WriteSignificandBigEndian(byte[] destination); + + int WriteSignificandBigEndian(byte[] destination, int startIndex); + + int WriteSignificandBigEndian(Span destination); + int WriteSignificandLittleEndian(byte[] destination); int WriteSignificandLittleEndian(byte[] destination, int startIndex); @@ -1736,11 +1779,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -1884,11 +1930,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // ? Explicit // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -2172,11 +2221,19 @@ namespace System // * TSelf Round(TSelf, MidpointRounding) // * Existing // * TSelf Round(TSelf, int, MidpointRounding) // * Existing // * TSelf Truncate(TSelf) // * Existing + // * bool TryWriteExponentBigEndian(byte[], out int) // ? Explicit // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandBigEndian(byte[], out int) // ? Explicit // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentBigEndian(byte[]) // ? Explicit + // * int WriteExponentBigEndian(byte[], int) // ? Explicit + // * int WriteExponentBigEndian(Span) // ? Explicit // * int WriteExponentLittleEndian(byte[]) // ? Explicit // * int WriteExponentLittleEndian(byte[], int) // ? Explicit // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandBigEndian(byte[]) // ? Explicit + // * int WriteSignificandBigEndian(byte[], int) // ? Explicit + // * int WriteSignificandBigEndian(Span) // ? Explicit // * int WriteSignificandLittleEndian(byte[]) // ? Explicit // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit // * int WriteSignificandLittleEndian(Span) // ? Explicit @@ -2348,11 +2405,19 @@ namespace System // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentBigEndian(byte[], out int) // ? Explicit // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandBigEndian(byte[], out int) // ? Explicit // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentBigEndian(byte[]) // ? Explicit + // * int WriteExponentBigEndian(byte[], int) // ? Explicit + // * int WriteExponentBigEndian(Span) // ? Explicit // * int WriteExponentLittleEndian(byte[]) // ? Explicit // * int WriteExponentLittleEndian(byte[], int) // ? Explicit // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandBigEndian(byte[]) // ? Explicit + // * int WriteSignificandBigEndian(byte[], int) // ? Explicit + // * int WriteSignificandBigEndian(Span) // ? Explicit // * int WriteSignificandLittleEndian(byte[]) // ? Explicit // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit // * int WriteSignificandLittleEndian(Span) // ? Explicit @@ -2575,11 +2640,19 @@ namespace System // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentBigEndian(byte[], out int) // ? Explicit // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandBigEndian(byte[], out int) // ? Explicit // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentBigEndian(byte[]) // ? Explicit + // * int WriteExponentBigEndian(byte[], int) // ? Explicit + // * int WriteExponentBigEndian(Span) // ? Explicit // * int WriteExponentLittleEndian(byte[]) // ? Explicit // * int WriteExponentLittleEndian(byte[], int) // ? Explicit // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandBigEndian(byte[]) // ? Explicit + // * int WriteSignificandBigEndian(byte[], int) // ? Explicit + // * int WriteSignificandBigEndian(Span) // ? Explicit // * int WriteSignificandLittleEndian(byte[]) // ? Explicit // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit // * int WriteSignificandLittleEndian(Span) // ? Explicit @@ -2790,15 +2863,17 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit - // * IBinaryNumber // ? Explicit // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) // * IComparable // Existing @@ -2941,11 +3016,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -3092,11 +3170,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -3235,11 +3316,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -3378,11 +3462,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -3532,11 +3619,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -3700,11 +3790,19 @@ namespace System // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentBigEndian(byte[], out int) // ? Explicit // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandBigEndian(byte[], out int) // ? Explicit // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentBigEndian(byte[]) // ? Explicit + // * int WriteExponentBigEndian(byte[], int) // ? Explicit + // * int WriteExponentBigEndian(Span) // ? Explicit // * int WriteExponentLittleEndian(byte[]) // ? Explicit // * int WriteExponentLittleEndian(byte[], int) // ? Explicit // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandBigEndian(byte[]) // ? Explicit + // * int WriteSignificandBigEndian(byte[], int) // ? Explicit + // * int WriteSignificandBigEndian(Span) // ? Explicit // * int WriteSignificandLittleEndian(byte[]) // ? Explicit // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit // * int WriteSignificandLittleEndian(Span) // ? Explicit @@ -4002,11 +4100,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -4150,11 +4251,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -4298,14 +4402,17 @@ namespace System // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) - // * int WriteLittleEndian(byte[]) - // * int WriteLittleEndian(byte[], int) - // * int WriteLittleEndian(Span) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -4440,14 +4547,17 @@ namespace System // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteLittleEndian(byte[], out int) - // * int WriteLittleEndian(byte[]) - // * int WriteLittleEndian(byte[], int) - // * int WriteLittleEndian(Span) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit + // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit + // * int WriteLittleEndian(byte[], int) // ? Explicit + // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) @@ -4581,11 +4691,14 @@ namespace System // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -4727,12 +4840,15 @@ namespace System.Numerics // * long GetShortestBitLength() // ? Explicit - BigInteger exposes `long GetBitLength()` // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit - // * int WriteLittleEndian(byte[]) // ? Explicit - BigInteger exposes `bool TryWriteBytes(Span destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false)` + // * int WriteBigEndian(byte[]) // ? Explicit - BigInteger exposes `bool TryWriteBytes(Span destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false)` + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit + // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit // * IBinaryNumber @@ -4956,11 +5072,14 @@ namespace System.Runtime.InteropServices // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -5097,11 +5216,14 @@ namespace System.Runtime.InteropServices // * long GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) - // * TSelf ReverseEndianness(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) + // * bool TryWriteBigEndian(byte[], out int) // ? Explicit // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit + // * int WriteBigEndian(byte[]) // ? Explicit + // * int WriteBigEndian(byte[], int) // ? Explicit + // * int WriteBigEndian(Span) // ? Explicit // * int WriteLittleEndian(byte[]) // ? Explicit // * int WriteLittleEndian(byte[], int) // ? Explicit // * int WriteLittleEndian(Span) // ? Explicit @@ -5256,11 +5378,19 @@ namespace System.Runtime.InteropServices // * TSelf Round(TSelf, MidpointRounding) // * TSelf Round(TSelf, int, MidpointRounding) // * TSelf Truncate(TSelf) + // * bool TryWriteExponentBigEndian(byte[], out int) // ? Explicit // * bool TryWriteExponentLittleEndian(byte[], out int) // ? Explicit + // * bool TryWriteSignificandBigEndian(byte[], out int) // ? Explicit // * bool TryWriteSignificandLittleEndian(byte[], out int) // ? Explicit + // * int WriteExponentBigEndian(byte[]) // ? Explicit + // * int WriteExponentBigEndian(byte[], int) // ? Explicit + // * int WriteExponentBigEndian(Span) // ? Explicit // * int WriteExponentLittleEndian(byte[]) // ? Explicit // * int WriteExponentLittleEndian(byte[], int) // ? Explicit // * int WriteExponentLittleEndian(Span) // ? Explicit + // * int WriteSignificandBigEndian(byte[]) // ? Explicit + // * int WriteSignificandBigEndian(byte[], int) // ? Explicit + // * int WriteSignificandBigEndian(Span) // ? Explicit // * int WriteSignificandLittleEndian(byte[]) // ? Explicit // * int WriteSignificandLittleEndian(byte[], int) // ? Explicit // * int WriteSignificandLittleEndian(Span) // ? Explicit From 2112ed6e0d0717315720b9fc969610c6ec11e26c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:31:09 -0700 Subject: [PATCH 28/35] Removing CLong and CULong --- accepted/2021/statics-in-interfaces/README.md | 308 +----------------- 1 file changed, 3 insertions(+), 305 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 34b525a88..a9d11fade 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -269,9 +269,7 @@ interface "IUnsignedNumber" class "BigInteger" class "Byte" class "Char" -class "CLong" class "Complex" -class "CULong" class "DateOnly" class "DateTime" class "DateTimeOffset" @@ -307,22 +305,12 @@ class "ValueType" "IUnsignedNumber" <|-- "Byte" "ValueType" <|-- "Byte" -"IBinaryInteger" <|-- "CLong" -"IMinMaxValue" <|-- "CLong" -"IUnsignedNumber" <|-- "CLong" -"ValueType" <|-- "CLong" - "IBinaryInteger" <|-- "Char" "IConvertible" <|-- "Char" "IMinMaxValue" <|-- "Char" "IUnsignedNumber" <|-- "Char" "ValueType" <|-- "Char" -"IBinaryInteger" <|-- "CULong" -"IMinMaxValue" <|-- "CULong" -"IUnsignedNumber" <|-- "CULong" -"ValueType" <|-- "CULong" - "IAdditionOperators" <|-- "Complex" "IDivisionOperators" <|-- "Complex" "IMultiplyOperators" <|-- "Complex" @@ -486,7 +474,7 @@ class "ValueType" @enduml --> -![UML](http://www.plantuml.com/plantuml/svg/h9ZFKjiy4C3lVefCpd3u-2ZjWUcq12YP0PB1SU-Ait5KPCcLLe0xVVWcWR6mx2Xh1oxCIgkVzu-YNUcRGQRHvYBY4a4lMGg3uNYaye9fDXSmt35-FllgJyadqCWRQox1WEPCy3yCkP8Z9iISfOzrfQlVbc4hzrhfd24sRPaoRLvNn22MtghuxPFDPN71fC-iJJQuDOtlYmNVk34fG3DKshog7Grc4ro1Nlz_06C5hjSrbpt1U04IEPRLgbRj2owPBg-5OiXbDbLSuXW0FdywTSusrCSI8GCTqBYt-Nod0Zvp0oIl_Et0pSvmUFgNa6h8GQAdxgln9sveCVRtaE1OqcovUYcKt2I3YMihqqrEswsffI6WGKZKJLc0dYl1q_0dnv8KfrkLCSrnbU_ZtN5vnrv-Cc6XVLujhB2cOxplraEy43nbn9tjrfGTF-NjtERK1JCGc7uxd3Q8eq4ILXcj87s41K4pPcZrDlC4vPcsCjsfF5NFeCD9V50AmnhnYY-nOsHZdabO1E8RspbgblOuysQQPqgg753lsw39zdY2ZBL_niUxDLDX3LdVjFaQjP-EWvr_vt-FZsbdTFXaw4i-t6Y_Kf1t3WKMTIWcFittPysYEZZOoufgRKqGus348kTtHX-89jIrlkZ8wxj84I4Lshw9Qw-rxQTKJrWKBlq16lsNxiDwCOFjGazck6VeosmlNeVvtgnsXySpN93wC2FI3wq9RHnpz9OtGA7tSG5R_8ug4FSGnRzd1HbXYdyXwqg9kjpQF8pNMH8kSiwQ82bm6N880ebK8CYaiVmecuYN0pgfF3ntdLhP08dKUvBYHEvyzvBMAFglpQ6Qpo5HysM536e-dQI26JCONl3ihKySLaCbGYMCLamxuLR9p4agBmIyE3cfJLyoX8aKPMrWndDe34oMImFeXY7bEHDELdOktAehQVDA-67veX9kc5XMmbZYVsVlfVzFtajdfpNDao_lnIawd--tPQOI9_DVa3enhWKhvZ8JJjpujWb-DP3KZKhgLYLrinBFhiGpRFjeC2kBpSxmMdvYLNQvftTo0O8poDEb4VgxiKr1_PsJ_Fb_fTf1gkf048RHULRb7YGxq9awS_z2u818XEQh1Pn-h_zR9btLEUpf76RPdhUlIpP4nhQm_8JRZk6qPRZi6KwRzX0B5SA6lDWI5rlIOdjOUoyHEc-QJjkcux7I-yoXltC7eyZBCH-FXocy9e_7jijPeLOTNziRlZOsVCsFpxNhA1KQ8PvFVq2-FcNvNW3ypmrZ-FTh0V6rWFZo--Lh0VB30dIMdvQXLMR5Q9N_DzqBaLXbL9XMcPMdLMP5QfLPgLfbLh1McPQjLThJHySPAmMFmsOyLXWUImlFVm5yMxaUOtdDVNjjq2qvkkwSJhTNnXXjswm7GB1XosnwAXlLX2SN6vvNRDam6qlRE2gK9Xl-qspi_epDIbt2QSjm6aJ1AJ0u9cQqM1A3Ss9mIGmkYS4jCUFNc1YS4eDBOd1938w96GNNoEYM6Pr2erDgT8pDnBnkd8uRfyEfZ6wnqUd5vSgZLXlTGgVBnkbSBzT-bG2NRSEnrE0G6PnBnOrNZ8nkcT5fttGypHvTPvzOydbYoTTJCL_xTxx6p-U1aylLEchYwv29hzS5V2yWldtImTVx2huMCDyBcEy5p9TFFVZwqGdVVq1yVDdjlTMZSwz7jrj2kWL7zzXwlqVdsEWQMs_vw1vRR_he71jTO-jz7zrZctH-U0yEhydrvW_lsVNs3-yT7Dwpmrjs-EQBjINCVtzSThc_Rk_dumC0) +![UML](http://www.plantuml.com/plantuml/svg/h9XHKzim383VyojwVOQ7CSRsmEqs2epU3TeZxTxTL4qz7BkpPI2x_VYHmZd4JesIqfUUREcBB3cMd6y6cKPRY8HB1BrY6Go6uv4gDaopXO3XZl7JsLT_Ijw3HXxOd8C1pPdWVnbo9KTCY0NBxffA5tyimrRkfT85GmnzcJ9jdYrI42lFAdrvP6YMRfZqcCt9WDlG-BvSycePamreXagRPxM3mMo2Qz1F_xTWhC0dkz3i7iPBaCYnT5QjscTSCbrU2iMGotogkCGn07p-TEoS2jN74Y477T6uiSLYfm8-S0EaLVdRWPkTuV3qpo7JK814JzrNu_VSq6Bixo71iQJvSl6uKR9A1XENLcPLJjkzQQGXea58r5Mv0RrGWcVnHuubAKu_LSuqntNn5k-Qosls-8i92-tpQcc5DHtZVMq5yetW6QFkR6TJTdoKltE3gJDc83BzSZXLY8F1FAuoMaDs1qk2PihGwctc2SepRMMsKtcg7a37atYh5COrqZLVOSV8fZoNi8p4DxKBr2phSURDDC-LL0MWVck3phV74-IizJ4XtjbCXJLaVTEsrgJzT1pi_9t-EpoadT7naw4lUN-d_Kf1tZaKMDAXc8GqBpd-cp-8_wAifD7Mn3aEHYnoVcVqZcX2NUkBJho-YnWHGg7jcxZsMjj-IlM49V7I7wSHttGVrfCPQHTwCsCzGrzcU_7QR-rXjTi_dl62r8UPa5wq41eSS_IMDqAXzt4HNxoEAXxt2CM_PyKOSOf_8UjAIRhSsZoCrraIBdBEcJWfSXbo21A9NY08fB5yBv-8bmCwgTmtTnrRsIY9q7iIuqJiVDyaFQ7eRrkD2Z-79E6N5J8e_7II2MRCO7Z6yvS-SUY6IWGdZDQidgbEL06FJZvd21CfoiR0Z1SG34nMAmDO3qF62oPgMTc5gAqkf2sSyCFofHEkc5WvOIpnmybhwUFHQ-dakA5vzEMrE4Njn9jj9N7YPF4RibfC6_58kSn5BLPhg-Bh1kPDf-PDh-PDj-QUNtFFiUrtWLcvgPBlTVN4mbkdDzwi4GcrGvvkZF2_L3ksKHW8mZ2QKnKz83g03CZe7n4y6O6HLjyKyFPkVyRspjZR2d4RId8RPQvVIEpkg6NPxdUe2pP4niQmNB8XB3Q4nPQms18McyyIRcbEUfrx6WOUptPulBJn-036yy-6nwEwXqyjLxuUYVbw6EPhVdmkVS_cUdZUVFe1-NnZvti1y5zlfSBVhmN4rmBYo_NBzmBaXmNeS3WhGwlCYj4g_z-EBaHYbL5XMcLMdbQP5QbLPgLgbLd1McLQjbQfTnyjJAmKl0qeyLfXU2ejFFy2-67bbSgFrosc7uvkoT5jvtHyuw4l3jjcmoo2JLjcsnbFxn_kN6ouNx5jmsmgRVEDK9fi-gVPrd2QmuIwXEEMuT3-m2amE2PcLbKIWrDYS4eCJed1CJ7pl98Od1A3Ks9mIWoEYPbvjiZebXdTGgDRQdICpMouRPpE6wV3gOokiT7fmMM6tggDRg7JRUDqhfTJdat3QTjmAZKuHGR7Kl4A9KL6jypel6ywdcRVNMUVMF9zOidNKp5V-tS-ni_tYQUtTNNKnDSX4r_VDl2rWFZw6G1VNtVmjO3vMi1yBM2-VXx0rmyL-7u1yV5XT-wj7frxFRgyOAHhS7IFBVTxT8sDxh7rbe_kiUMcZwwnqJsstlVHWzXwvuVduF2UN6_-y9vTR__mti7XCJkyPwS5z0dK4kO_lrOwNX-Nv_ts0W00) ### Base Interfaces @@ -870,7 +858,7 @@ namespace System.Numerics // The `rotateAmount` and `shiftAmount` parameters have similar considerations. // // Finally, variable sized types may return different results on different platforms. - // Consider for example `nint`, `nuint`, `CLong`, and `CULong` where `LeadingZeroCount(5)` + // Consider for example `nint` and `nuint` where `LeadingZeroCount(5)` // returns a different result based on if we're on a 32-bit or 64-bit system. A user // could likewise implement `BigInteger` such that it is represented via a `nuint[]`. // @@ -5002,296 +4990,6 @@ namespace System.Numerics namespace System.Runtime.InteropServices { - public struct CLong - : IBinaryInteger, - IMinMaxValue, - ISignedNumber - { - // Explicitly implemented interfaces - // * IAdditiveIdentity - // * TSelf AdditiveIdentity { get; } - // * IMultiplicativeIdentity - // * TSelf MultiplicativeIdentity { get; } - // * INumberBase - // * One { get; } - // * Zero { get; } - // * ISignedNumber - // * TSelf NegativeOne { get; } - - // Implicitly Implemented interfaces - // * IMinMaxValue - // * TSelf MaxValue { get; } - // * TSelf MinValue { get; } - // - // * IAdditionOperators - // * TSelf operator +(TSelf, TSelf) - // * TSelf operator checked +(TSelf, TSelf) - // * IBitwiseOperators - // * TSelf operator &(TSelf, TSelf) - // * TSelf operator |(TSelf, TSelf) - // * TSelf operator ^(TSelf, TSelf) - // * TSelf operator ~(TSelf) - // * IComparisonOperators - // * bool operator <(TSelf, TSelf) - // * bool operator <=(TSelf, TSelf) - // * bool operator >(TSelf, TSelf) - // * bool operator >=(TSelf, TSelf) - // * IDecrementOperators - // * TSelf operator --(TSelf) - // * TSelf operator checked --(TSelf) - // * IDivisionOperators - // * TSelf operator /(TSelf, TSelf) - // * TSelf operator checked /(TSelf, TSelf) - // * IIncrementOperators - // * TSelf operator ++(TSelf) - // * TSelf operator checked ++(TSelf) - // * IModulusOperators - // * TSelf operator %(TSelf, TSelf) - // * IMultiplyOperators - // * TSelf operator *(TSelf, TSelf) - // * TSelf operator checked *(TSelf, TSelf) - // * IShiftOperators - // * TSelf operator <<(TSelf, TSelf) - // * TSelf operator >>(TSelf, TSelf) - // * TSelf operator >>>(TSelf, TSelf) - // * TSelf operator <<(TSelf, int) - // * TSelf operator >>(TSelf, int) - // * TSelf operator >>>(TSelf, int) - // * ISubtractionOperators - // * TSelf operator -(TSelf, TSelf) - // * TSelf operator checked -(TSelf, TSelf) - // * IUnaryNegationOperators - // * TSelf operator -(TSelf) - // * TSelf operator checked -(TSelf) - // * IUnaryPlusOperators - // * TSelf operator +(TSelf) - // - // * IBinaryInteger - // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * int GetShortestByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit - // * TSelf LeadingZeroCount(TSelf) - // * TSelf PopCount(TSelf) - // * TSelf RotateLeft(TSelf, int) - // * TSelf RotateRight(TSelf, int) - // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteBigEndian(byte[], out int) // ? Explicit - // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit - // * int WriteBigEndian(byte[]) // ? Explicit - // * int WriteBigEndian(byte[], int) // ? Explicit - // * int WriteBigEndian(Span) // ? Explicit - // * int WriteLittleEndian(byte[]) // ? Explicit - // * int WriteLittleEndian(byte[], int) // ? Explicit - // * int WriteLittleEndian(Span) // ? Explicit - // * IBinaryNumber - // * bool IsPow2(TSelf) - // * TSelf Log2(TSelf) - // * IComparable - // * int CompareTo(object?) - // * int CompareTo(TSelf) - // * IEqualityOperators - // * bool operator ==(TSelf, TSelf) // * Existing - // * bool operator !=(TSelf, TSelf) // * Existing - // * IEquatable // Existing - // * bool Equals(TSelf) // * Existing - // * IFormattable - // * string ToString(string?, IFormatProvider?) - // * INumber - // * TSelf Clamp(TSelf, TSelf, TSelf) - // * TSelf CopySign(TSelf, TSelf) - // * TSelf Max(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit - // * TSelf Min(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // ? Explicit - // * TSelf Parse(string, NumberStyles, IFormatProvider?) - // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) - // * int Sign(TSelf) - // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) - // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) - // * INumberBase - // * TSelf Abs(TSelf) - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) - // * bool IsCanonical(TSelf) - // * bool IsEvenInteger(TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsInteger(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsOddInteger(TSelf) - // * bool IsPositive(TSelf) - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSignalingNaN(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit - // * bool IsZero(TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitude(TSelf, TSelf) - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit - // * bool TryConvertFromChecked(TOther, out TSelf) - // * bool TryConvertFromSaturating(TOther, out TSelf) - // * bool TryConvertFromTruncating(TOther, out TSelf) - // * bool TryConvertToChecked(TOther, out TSelf) - // * bool TryConvertToSaturating(TOther, out TSelf) - // * bool TryConvertToTruncating(TOther, out TSelf) - // * IParsable - // * TSelf Parse(string, IFormatProvider?) - // * bool TryParse(string?, IFormatProvider?, out TSelf) - // * ISpanFormattable - // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) - // * ISpanParsable - // * TSelf Parse(ReadOnlySpan, IFormatProvider?) - // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) - } - - public struct CULong - : IBinaryInteger, - IMinMaxValue, - IUnsignedNumber - { - // Explicitly implemented interfaces - // * IAdditiveIdentity - // * TSelf AdditiveIdentity { get; } - // * IMultiplicativeIdentity - // * TSelf MultiplicativeIdentity { get; } - // * INumberBase - // * One { get; } - // * Zero { get; } - - // Implicitly Implemented interfaces - // * IMinMaxValue - // * TSelf MaxValue { get; } - // * TSelf MinValue { get; } - // - // * IAdditionOperators - // * TSelf operator +(TSelf, TSelf) - // * TSelf operator checked +(TSelf, TSelf) - // * IBitwiseOperators - // * TSelf operator &(TSelf, TSelf) - // * TSelf operator |(TSelf, TSelf) - // * TSelf operator ^(TSelf, TSelf) - // * TSelf operator ~(TSelf) - // * IComparisonOperators - // * bool operator <(TSelf, TSelf) - // * bool operator <=(TSelf, TSelf) - // * bool operator >(TSelf, TSelf) - // * bool operator >=(TSelf, TSelf) - // * IDecrementOperators - // * TSelf operator --(TSelf) - // * TSelf operator checked --(TSelf) - // * IDivisionOperators - // * TSelf operator /(TSelf, TSelf) - // * TSelf operator checked /(TSelf, TSelf) - // * IIncrementOperators - // * TSelf operator ++(TSelf) - // * TSelf operator checked ++(TSelf) - // * IModulusOperators - // * TSelf operator %(TSelf, TSelf) - // * IMultiplyOperators - // * TSelf operator *(TSelf, TSelf) - // * TSelf operator checked *(TSelf, TSelf) - // * IShiftOperators - // * TSelf operator <<(TSelf, TSelf) - // * TSelf operator >>(TSelf, TSelf) - // * TSelf operator >>>(TSelf, TSelf) - // * TSelf operator <<(TSelf, int) - // * TSelf operator >>(TSelf, int) - // * TSelf operator >>>(TSelf, int) - // * ISubtractionOperators - // * TSelf operator -(TSelf, TSelf) - // * TSelf operator checked -(TSelf, TSelf) - // * IUnaryNegationOperators - // * TSelf operator -(TSelf) - // * TSelf operator checked -(TSelf) - // * IUnaryPlusOperators - // * TSelf operator +(TSelf) - // - // * IBinaryInteger - // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit - // * TSelf LeadingZeroCount(TSelf) - // * TSelf PopCount(TSelf) - // * TSelf RotateLeft(TSelf, int) - // * TSelf RotateRight(TSelf, int) - // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteBigEndian(byte[], out int) // ? Explicit - // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit - // * int WriteBigEndian(byte[]) // ? Explicit - // * int WriteBigEndian(byte[], int) // ? Explicit - // * int WriteBigEndian(Span) // ? Explicit - // * int WriteLittleEndian(byte[]) // ? Explicit - // * int WriteLittleEndian(byte[], int) // ? Explicit - // * int WriteLittleEndian(Span) // ? Explicit - // * IBinaryNumber - // * bool IsPow2(TSelf) - // * TSelf Log2(TSelf) - // * IComparable - // * int CompareTo(object?) - // * int CompareTo(TSelf) - // * IEqualityOperators - // * bool operator ==(TSelf, TSelf) // * Existing - // * bool operator !=(TSelf, TSelf) // * Existing - // * IEquatable // Existing - // * bool Equals(TSelf) // * Existing - // * IFormattable - // * string ToString(string?, IFormatProvider?) - // * INumber - // * TSelf Clamp(TSelf, TSelf, TSelf) - // * TSelf CopySign(TSelf, TSelf) // ? Explicit - // * TSelf Max(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit - // * TSelf Min(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // ? Explicit - // * TSelf Parse(string, NumberStyles, IFormatProvider?) - // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) - // * int Sign(TSelf) - // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) - // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) - // * INumberBase - // * TSelf Abs(TSelf) // ? Explicit - // * TSelf CreateChecked(TOther) - // * TSelf CreateSaturating(TOther) - // * TSelf CreateTruncating(TOther) - // * bool IsCanonical(TSelf) // ? Explicit - // * bool IsEvenInteger(TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsInteger(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit - // * bool IsOddInteger(TSelf) - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSignalingNaN(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit - // * bool IsZero(TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit - // * bool TryConvertFromChecked(TOther, out TSelf) - // * bool TryConvertFromSaturating(TOther, out TSelf) - // * bool TryConvertFromTruncating(TOther, out TSelf) - // * bool TryConvertToChecked(TOther, out TSelf) - // * bool TryConvertToSaturating(TOther, out TSelf) - // * bool TryConvertToTruncating(TOther, out TSelf) - // * IParsable - // * TSelf Parse(string, IFormatProvider?) - // * bool TryParse(string?, IFormatProvider?, out TSelf) - // * ISpanFormattable - // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) - // * ISpanParsable - // * TSelf Parse(ReadOnlySpan, IFormatProvider?) - // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) - } - public struct NFloat : IBinaryFloatingPointIeee754, IMinMaxValue @@ -5882,7 +5580,7 @@ This leaves us with the `TryConvertFrom`/`TryConvertTo` pattern for the majority #### Why no `IConvertible`, `IExplicitOperators`, or `IImplicitOperators` -We could expose these, but they have the same general limitations as the `Create` APIs. Additionally, it vastly increases the number of interfaces implemented since there are 11 primitive integer types (`byte`, `char`, `short`, `int`, `long`, `nint`, `sbyte`, `ushort`, `uint`, `ulong`, and `nuint`), 3 primitive floating-point types (`decimal`, `double`, and `float`), and some 6 other ABI primitive types (`Half`, `Int128`, `UInt128`, `NFloat`, `CLong`, and `CULong`). Supporting single-direction conversions for these requires at least 14 interfaces. Bi-directional doubles that to 24. +We could expose these, but they have the same general limitations as the `Create` APIs. Additionally, it vastly increases the number of interfaces implemented since there are 11 primitive integer types (`byte`, `char`, `short`, `int`, `long`, `nint`, `sbyte`, `ushort`, `uint`, `ulong`, and `nuint`), 3 primitive floating-point types (`decimal`, `double`, and `float`), and some 4 other ABI primitive types (`Half`, `Int128`, `UInt128`, and `NFloat`). Supporting single-direction conversions for these requires at least 14 interfaces. Bi-directional doubles that to 24. ### Future Considerations From 89a76503d1f6148988a2910acc1c1bf596f03c32 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:34:46 -0700 Subject: [PATCH 29/35] Have GetShortestBitLength return `int` --- accepted/2021/statics-in-interfaces/README.md | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index a9d11fade..ff00277dc 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -909,10 +909,10 @@ namespace System.Numerics int GetByteCount(); - long GetShortestBitLength() + int GetShortestBitLength() { - long bitCount = (GetByteCount() * 8L); - return bitCount - long.CreateChecked(TSelf.LeadingZeroCount(this)); + int bitCount = checked(GetByteCount() * 8); + return bitCount - int.CreateChecked(TSelf.LeadingZeroCount(this)); } bool TryWriteBigEndian(Span destination, out int bytesWritten); @@ -1038,11 +1038,11 @@ namespace System.Numerics // These methods allow getting the underlying bytes that represent the IEEE 754 floating-point - long GetExponentShortestBitLength(); + int GetExponentShortestBitLength(); int GetExponentByteCount(); - long GetSignificandShortestBitLength(); + int GetSignificandShortestBitLength(); int GetSignificandByteCount(); @@ -1764,7 +1764,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -1915,7 +1915,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // ? Explicit // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -2201,9 +2201,9 @@ namespace System // * TSelf Ceiling(TSelf) // * Existing // * TSelf Floor(TSelf) // * Existing // * int GetExponentByteCount() // ? Explicit - // * long GetExponentShortestBitLength() // ? Explicit + // * int GetExponentShortestBitLength() // ? Explicit // * int GetSignificandByteCount() // ? Explicit - // * long GetSignificandShortestBitLength() // ? Explicit + // * int GetSignificandShortestBitLength () // ? Explicit // * TSelf Round(TSelf) // * Existing // * TSelf Round(TSelf, int) // * Existing // * TSelf Round(TSelf, MidpointRounding) // * Existing @@ -2385,9 +2385,9 @@ namespace System // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) // * int GetExponentByteCount() // ? Explicit - // * long GetExponentShortestBitLength() // ? Explicit + // * int GetExponentShortestBitLength() // ? Explicit // * int GetSignificandByteCount() // ? Explicit - // * long GetSignificandShortestBitLength() // ? Explicit + // * int GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) @@ -2620,9 +2620,9 @@ namespace System // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) // * int GetExponentByteCount() // ? Explicit - // * long GetExponentShortestBitLength() // ? Explicit + // * int GetExponentShortestBitLength() // ? Explicit // * int GetSignificandByteCount() // ? Explicit - // * long GetSignificandShortestBitLength() // ? Explicit + // * int GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) @@ -2848,7 +2848,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3001,7 +3001,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3155,7 +3155,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3301,7 +3301,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3447,7 +3447,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3604,7 +3604,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -3770,9 +3770,9 @@ namespace System // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) // * int GetExponentByteCount() // ? Explicit - // * long GetExponentShortestBitLength() // ? Explicit + // * int GetExponentShortestBitLength() // ? Explicit // * int GetSignificandByteCount() // ? Explicit - // * long GetSignificandShortestBitLength() // ? Explicit + // * int GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) @@ -4085,7 +4085,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -4236,7 +4236,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -4386,7 +4386,7 @@ namespace System // Implicitly Implemented interfaces // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() + // * int GetShortestBitLength() // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) @@ -4531,7 +4531,7 @@ namespace System // // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) - // * long GetBitLength() + // * int GetShortestBitLength() // * int GetByteCount() // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) @@ -4676,7 +4676,7 @@ namespace System // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - // * long GetShortestBitLength() // ? Explicit + // * int GetShortestBitLength() // ? Explicit // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -4825,7 +4825,7 @@ namespace System.Numerics // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() // ? Explicit - BigInteger exposes `int GetByteCount(bool isUnsigned = false)` - // * long GetShortestBitLength() // ? Explicit - BigInteger exposes `long GetBitLength()` + // * int GetShortestBitLength() // ? Explicit - BigInteger exposes `long GetBitLength()` // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) @@ -5068,9 +5068,9 @@ namespace System.Runtime.InteropServices // * TSelf Ceiling(TSelf) // * TSelf Floor(TSelf) // * int GetExponentByteCount() // ? Explicit - // * long GetExponentShortestBitLength() // ? Explicit + // * int GetExponentShortestBitLength() // ? Explicit // * int GetSignificandByteCount() // ? Explicit - // * long GetSignificandShortestBitLength() // ? Explicit + // * int GetSignificandShortestBitLength() // ? Explicit // * TSelf Round(TSelf) // * TSelf Round(TSelf, int) // * TSelf Round(TSelf, MidpointRounding) From fcb308445cfcb89bb3456bf7d6030c6be9414494 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:37:28 -0700 Subject: [PATCH 30/35] Moving ISpanParsable down to INumberBase --- accepted/2021/statics-in-interfaces/README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index ff00277dc..b4f3eb7e0 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -205,9 +205,6 @@ interface "IMultiplyOperators" interface "INumber" interface "INumberBase" interface "INumberConverter" -interface "INumberConverterChecked" -interface "INumberConverterSaturating" -interface "INumberConverterTruncating" interface "IPowerFunctions" interface "IRootFunctions" interface "IShiftOperators" @@ -245,19 +242,19 @@ interface "IUnsignedNumber" "ITrigonometricFunctions" <|-- "IFloatingPointIeee754" "IComparisonOperators" <|-- "INumber" -"IDivisionOperators" <|-- "INumber" "IModulusOperators" <|-- "INumber" "INumberBase" <|-- "INumber" -"ISpanFormattable" <|-- "INumber" -"ISpanParsable" <|-- "INumber" "IAdditionOperators" <|-- "INumberBase" "IAdditiveIdentity" <|-- "INumberBase" "IDecrementOperators" <|-- "INumberBase" +"IDivisionOperators" <|-- "INumberBase" "IEqualityOperators" <|-- "INumberBase" "IIncrementOperators" <|-- "INumberBase" "IMultiplicativeIdentity" <|-- "INumberBase" "IMultiplyOperators" <|-- "INumberBase" +"ISpanFormattable" <|-- "INumberBase" +"ISpanParsable" <|-- "INumberBase" "ISubtractionOperators" <|-- "INumberBase" "IUnaryPlusOperators" <|-- "INumberBase" "IUnaryNegationOperators" <|-- "INumberBase" @@ -474,7 +471,7 @@ class "ValueType" @enduml --> -![UML](http://www.plantuml.com/plantuml/svg/h9XHKzim383VyojwVOQ7CSRsmEqs2epU3TeZxTxTL4qz7BkpPI2x_VYHmZd4JesIqfUUREcBB3cMd6y6cKPRY8HB1BrY6Go6uv4gDaopXO3XZl7JsLT_Ijw3HXxOd8C1pPdWVnbo9KTCY0NBxffA5tyimrRkfT85GmnzcJ9jdYrI42lFAdrvP6YMRfZqcCt9WDlG-BvSycePamreXagRPxM3mMo2Qz1F_xTWhC0dkz3i7iPBaCYnT5QjscTSCbrU2iMGotogkCGn07p-TEoS2jN74Y477T6uiSLYfm8-S0EaLVdRWPkTuV3qpo7JK814JzrNu_VSq6Bixo71iQJvSl6uKR9A1XENLcPLJjkzQQGXea58r5Mv0RrGWcVnHuubAKu_LSuqntNn5k-Qosls-8i92-tpQcc5DHtZVMq5yetW6QFkR6TJTdoKltE3gJDc83BzSZXLY8F1FAuoMaDs1qk2PihGwctc2SepRMMsKtcg7a37atYh5COrqZLVOSV8fZoNi8p4DxKBr2phSURDDC-LL0MWVck3phV74-IizJ4XtjbCXJLaVTEsrgJzT1pi_9t-EpoadT7naw4lUN-d_Kf1tZaKMDAXc8GqBpd-cp-8_wAifD7Mn3aEHYnoVcVqZcX2NUkBJho-YnWHGg7jcxZsMjj-IlM49V7I7wSHttGVrfCPQHTwCsCzGrzcU_7QR-rXjTi_dl62r8UPa5wq41eSS_IMDqAXzt4HNxoEAXxt2CM_PyKOSOf_8UjAIRhSsZoCrraIBdBEcJWfSXbo21A9NY08fB5yBv-8bmCwgTmtTnrRsIY9q7iIuqJiVDyaFQ7eRrkD2Z-79E6N5J8e_7II2MRCO7Z6yvS-SUY6IWGdZDQidgbEL06FJZvd21CfoiR0Z1SG34nMAmDO3qF62oPgMTc5gAqkf2sSyCFofHEkc5WvOIpnmybhwUFHQ-dakA5vzEMrE4Njn9jj9N7YPF4RibfC6_58kSn5BLPhg-Bh1kPDf-PDh-PDj-QUNtFFiUrtWLcvgPBlTVN4mbkdDzwi4GcrGvvkZF2_L3ksKHW8mZ2QKnKz83g03CZe7n4y6O6HLjyKyFPkVyRspjZR2d4RId8RPQvVIEpkg6NPxdUe2pP4niQmNB8XB3Q4nPQms18McyyIRcbEUfrx6WOUptPulBJn-036yy-6nwEwXqyjLxuUYVbw6EPhVdmkVS_cUdZUVFe1-NnZvti1y5zlfSBVhmN4rmBYo_NBzmBaXmNeS3WhGwlCYj4g_z-EBaHYbL5XMcLMdbQP5QbLPgLgbLd1McLQjbQfTnyjJAmKl0qeyLfXU2ejFFy2-67bbSgFrosc7uvkoT5jvtHyuw4l3jjcmoo2JLjcsnbFxn_kN6ouNx5jmsmgRVEDK9fi-gVPrd2QmuIwXEEMuT3-m2amE2PcLbKIWrDYS4eCJed1CJ7pl98Od1A3Ks9mIWoEYPbvjiZebXdTGgDRQdICpMouRPpE6wV3gOokiT7fmMM6tggDRg7JRUDqhfTJdat3QTjmAZKuHGR7Kl4A9KL6jypel6ywdcRVNMUVMF9zOidNKp5V-tS-ni_tYQUtTNNKnDSX4r_VDl2rWFZw6G1VNtVmjO3vMi1yBM2-VXx0rmyL-7u1yV5XT-wj7frxFRgyOAHhS7IFBVTxT8sDxh7rbe_kiUMcZwwnqJsstlVHWzXwvuVduF2UN6_-y9vTR__mti7XCJkyPwS5z0dK4kO_lrOwNX-Nv_ts0W00) +![UML](http://www.plantuml.com/plantuml/svg/h9ZVKzi-3C3VyrVq-WmFNxwCxO7RRVnWz6xG7cdthgPgwisnEzi1ijiVlwHm2LPILqtXXPCjVIB9ZgJqYtLWN9x9I2Y7PWa93eQZIvsjmS1Sud3B-ldqCzrIZsYSQDbSeKKZG8e_u8HMbo3b799VljBrxnnS9_T6cmoSQ_io0MDVB6AKIs8LlpwoRHQlGNbCkjdYUXfV5mjHXJ5Uem6dZNrHEnfCnsw5flp_W3QNhhHhcptYQ87A2LVKLftQ5qA1AMwa1YTKEj7btWWHFtuuhPrggu_AbHHDGEC-p-PR5ToJiCYBYbm7ORUcW-XVOM8mG-M8EbKJZy8oSqpka1IkuFbo_RpMgZeCa3UvIgepxVR6EuQ01kEWRelIjRcM8Wa_SgHOUVgkKp32hR9Tl3kXxk3v1yWSk_Vr8fUvtJFVT-MIM4kH0FTcrpR5dezgtrooTG4M0zklnQb270rcH6MYdz244_YWjGjhn2knT7j65OjKuI8GMvpFdO6aHxsP6f5gfJDqPjVbc6rA0wRGyHYAzsmcChTiVTiLQzHTcGPR_yx_7X_pwcFuhUnFFjHfMgNPDuS3Y_Oev9H6uobPt007ErcHDr8480J6QJ1qAdb7DAEdz4L7PEPXPeJHvFeUN7UVwwvIFM5HkEs6QSmtdS3wCWEjkZSprA_xChkRrs6nqsvtU3vtDQG-p8ZrehMXjCpnfvy0XSuXWOm5AD4-tnS4GsOWnYT7xKoO51ZRQmINn9_i0wGUXJb46gdtYeuv4FD9nU5vef-xZ5OG8D5lupwaFSVQ88anXp9zOax1EqabYfbk7qNFgGBniqr0xPym4WdM3eON8dsT6OVrKk6m5YvNqEnKrLNYSorVWSEnaeMtC1KPjXR6owL5ronZ8ZAGZQppkMoihbMUrSAtN2nguHRaiXPAn_yxUolzV_9MEZlrD4y-lHKdhWdhVjDLQd4y_ub98yPUFcAXKjc8LMnLVkk5cU_KpFTgvhir8txDY6ERx_DfiQuEdqxuh2Ri7M-VmOqGQeUe6O_GFupD4VW_AR8V_wzKEqXL68R2C3hlgjo3k0ETgJFtBnGEYbG8trt0oNlvlMroa-xsyCXZsHvtgqisHCQci3oo8ImsXCMMiDWI5fjtIbvfjYATMw43hxj5l3tQU5o0yVYpuNdRRl6fvShNFH5VTq9ypO_FfMzjhgt1n_SVa2_lAhuN0FzpEnJ-VYqWlXOGNvvVlXSWFon0cyDP6HfbLen6-NzBkHA9KMQ5QPHPUHfbLgH6cPMgKMO5QvHPsHgblNsqCBbIy7HOYSSAmsDfuVaNmBULwnMMrotcPODkoT5XvdIy_T0NjscpNW31XYcpwQsizmzlBhQyhzWmOJQMjlEDK9fi-AVPs70wXsbr2OSfmxNzWKjWS4lCMLLC34w9mIKnk2G6jyISvyN4u9GON1A3Is9mJCpPOesCRfdHAJGwfKR7s1p1redJSU9qs9NH9JOwBbpEq6krqIrqkaoSplLoxcVJS9as74iD3f71kLHSeSJ8w9OPdUPDnztitdNs4qi-drZoTLVCr_wTh_7p-S39RLqzQkBh8HDVRnluMa1y_JI1hzSTV2rWlXOmNmkOhvy7yFL31Ru-G7nUx2w3Le-knKkt2qQw1KVts7g_H-VOw1fRR_de7bjl-kWS6rrZwtqVNMERTNvu3mwloVNc3-_PzVOFxnqSthF3MtRuvXEe9Sn_VwrqkZslhyVz3G00) ### Base Interfaces @@ -1285,7 +1282,6 @@ namespace System.Numerics : IComparisonOperators, // implies IEqualityOperators IModulusOperators, INumberBase, - ISpanParsable // implies IParsable where TSelf : INumber { public static TSelf Clamp(TSelf value, TSelf min, TSelf max) @@ -1414,6 +1410,7 @@ namespace System.Numerics IMultiplicativeIdentity, IMultiplyOperators, ISpanFormattable, // implies IFormattable + ISpanParsable // implies IParsable ISubtractionOperators, IUnaryPlusOperators, IUnaryNegationOperators From 405b78f1709092b12bcd6a1eda29da441c44aa38 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:41:56 -0700 Subject: [PATCH 31/35] Fixing the documented DIM implementation for Max, MaxNumber, Min, and MinNumber --- accepted/2021/statics-in-interfaces/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index b4f3eb7e0..76f7a786e 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1319,17 +1319,17 @@ namespace System.Numerics public static virtual TSelf Max(TSelf x, TSelf y) { - if (val1 != val2) + if (x != y) { - if (!IsNaN(val1)) + if (!IsNaN(x)) { - return val2 < val1 ? val1 : val2; + return y < x ? x : y; } - return val1; + return x; } - return IsNegative(val2) ? val1 : val2; + return IsNegative(y) ? x : y; } public static virtual TSelf MaxNumber(TSelf x, TSelf y) @@ -1349,12 +1349,12 @@ namespace System.Numerics public static virtual TSelf Min(TSelf x, TSelf y) { - if (val1 != val2 && !IsNaN(val1)) + if ((x != y) && !IsNaN(x)) { - return val1 < val2 ? val1 : val2; + return x < y ? x : y; } - return IsNegative(val1) ? val1 : val2; + return IsNegative(x) ? x : y; } public static virtual TSelf MinNumber(TSelf x, TSelf y) From 370282f671e51640a7beb4590a567ed077f08e73 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:45:55 -0700 Subject: [PATCH 32/35] Removing the DIM from IsPositive --- accepted/2021/statics-in-interfaces/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 76f7a786e..66fd69717 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1541,7 +1541,7 @@ namespace System.Numerics static abstract bool IsOddInteger(TSelf value); - public static virtual bool IsPositive(TSelf value) => !IsNegative(value); + static abstract bool IsPositive(TSelf value); public static virtual bool IsPositiveInfinity(TSelf value) => IsPositive(value) && IsInfinity(value); From 357f8fc8a9e25e618e7216dfb2c320ee8946c08b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:47:50 -0700 Subject: [PATCH 33/35] Removing constants from the primitives that we aren't exposing --- accepted/2021/statics-in-interfaces/README.md | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 66fd69717..4a412aae3 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1692,12 +1692,8 @@ namespace System IMinMaxValue, IUnsignedNumber { - public const byte AdditiveIdentity = 0; // ? Expose public const byte MaxValue = 255; // Existing public const byte MinValue = 0; // Existing - public const byte MultiplicativeIdentity = 1; // ? Expose - public const byte One = 1; // ? Expose - public const byte Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -1843,12 +1839,8 @@ namespace System IMinMaxValue, IUnsignedNumber { - public const short AdditiveIdentity = 0; // ? Expose public const short MaxValue = 65535; // Existing public const short MinValue = 0; // Existing - public const short MultiplicativeIdentity = 1; // ? Expose - public const short One = 1; // ? Expose - public const short Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -2148,12 +2140,9 @@ namespace System // Decimal exposes a member named MinusOne - public const decimal AdditiveIdentity = 0; // ? Expose public const decimal MaxValue = 79228162514264337593543950335m; // Existing public const decimal MinusOne = -1; // Existing - "Conflicts" with NegativeOne public const decimal MinValue = -79228162514264337593543950335m; // Existing - public const decimal MultiplicativeIdentity = 1; // ? Expose - public const decimal NegativeOne = -1; // ? Expose public const decimal One = 1; // Existing public const decimal Zero = 0; // Existing @@ -2297,17 +2286,12 @@ namespace System IConvertible, IMinMaxValue { - public const double AdditiveIdentity = 0; // ? Expose public const double E = Math.E; public const double MaxValue = 1.7976931348623157E+308; // Existing public const double MinValue = -1.7976931348623157E+308; // Existing - public const double MultiplicativeIdentity = 1; // ? Expose - public const double NegativeOne = -1; // ? Expose public const double NegativeZero = -0.0; - public const double One = 1; // ? Expose public const double Pi = Math.PI; public const double Tau = Math.Tau; - public const double Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -2773,13 +2757,8 @@ namespace System IMinMaxValue, ISignedNumber { - public const short AdditiveIdentity = 0; // ? Expose public const short MaxValue = 32767; // Existing public const short MinValue = -32768; // Existing - public const short MultiplicativeIdentity = 1; // ? Expose - public const short NegativeOne = -1; // ? Expose - public const short One = 1; // ? Expose - public const short Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -2926,13 +2905,8 @@ namespace System IMinMaxValue, ISignedNumber { - public const int AdditiveIdentity = 0; // ? Expose public const int MaxValue = 2147483647; // Existing public const int MinValue = -2147483648; // Existing - public const int MultiplicativeIdentity = 1; // ? Expose - public const int NegativeOne = -1; // ? Expose - public const int One = 1; // ? Expose - public const int Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -3080,13 +3054,8 @@ namespace System IMinMaxValue, ISignedNumber { - public const long AdditiveIdentity = 0; // ? Expose public const long MaxValue = 9223372036854775807; // Existing public const long MinValue = -9223372036854775808; // Existing - public const long MultiplicativeIdentity = 1; // ? Expose - public const long NegativeOne = -1; // ? Expose - public const long One = 1; // ? Expose - public const long Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -3529,13 +3498,8 @@ namespace System IMinMaxValue, ISignedNumber { - public const sbyte AdditiveIdentity = 0; // ? Expose public const sbyte MaxValue = 127; // Existing public const sbyte MinValue = -128; // Existing - public const sbyte MultiplicativeIdentity = 1; // ? Expose - public const sbyte NegativeOne = -1; // ? Expose - public const sbyte One = 1; // ? Expose - public const sbyte Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -3682,17 +3646,12 @@ namespace System IConvertible, IMinMaxValue { - public const float AdditiveIdentity = 0; // ? Expose public const float E = MathF.E; public const float MaxValue = 3.40282346638528859e+38f; // Existing public const float MinValue = -3.40282346638528859e+38f; // Existing - public const float MultiplicativeIdentity = 1; // ? Expose - public const float NegativeOne = -1; // ? Expose public const float NegativeZero = -0.0f; - public const float One = 1; // ? Expose public const float Pi = Math.PI; public const float Tau = Math.Tau; - public const float Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -4013,12 +3972,8 @@ namespace System IMinMaxValue, IUnsignedNumber { - public const short AdditiveIdentity = 0; // ? Expose public const short MaxValue = 65535; // Existing public const short MinValue = 0; // Existing - public const short MultiplicativeIdentity = 1; // ? Expose - public const short One = 1; // ? Expose - public const short Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -4164,12 +4119,8 @@ namespace System IMinMaxValue, IUnsignedNumber { - public const uint AdditiveIdentity = 0; // ? Expose public const uint MaxValue = 4294967295; // Existing public const uint MinValue = 0; // Existing - public const uint MultiplicativeIdentity = 1; // ? Expose - public const uint One = 1; // ? Expose - public const uint Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity @@ -4315,12 +4266,8 @@ namespace System IMinMaxValue, IUnsignedNumber { - public const ulong AdditiveIdentity = 0; // ? Expose public const ulong MaxValue = 18446744073709551615; // Existing public const ulong MinValue = 0; // Existing - public const ulong MultiplicativeIdentity = 1; // ? Expose - public const ulong One = 1; // ? Expose - public const ulong Zero = 0; // ? Expose // Explicitly implemented interfaces // * IAdditiveIdentity From 53199b97b8bec70a37e7de10f5cad0003d66f488 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:50:06 -0700 Subject: [PATCH 34/35] Have `char` explicitly implement the generic math interfaces --- accepted/2021/statics-in-interfaces/README.md | 91 ++++++++++--------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 4a412aae3..060c558ac 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1899,71 +1899,65 @@ namespace System // * TSelf operator checked -(TSelf) // * IUnaryPlusOperators // * TSelf operator +(TSelf) - - // Implicitly Implemented interfaces + // // * IBinaryInteger // * (TSelf, TSelf) DivRem(TSelf, TSelf) // * int GetByteCount() - // * int GetShortestBitLength() // ? Explicit - // * TSelf LeadingZeroCount(TSelf) // ? Explicit + // * int GetShortestBitLength() + // * TSelf LeadingZeroCount(TSelf) // * TSelf PopCount(TSelf) // * TSelf RotateLeft(TSelf, int) // * TSelf RotateRight(TSelf, int) // * TSelf TrailingZeroCount(TSelf) - // * bool TryWriteBigEndian(byte[], out int) // ? Explicit - // * bool TryWriteLittleEndian(byte[], out int) // ? Explicit - // * int WriteBigEndian(byte[]) // ? Explicit - // * int WriteBigEndian(byte[], int) // ? Explicit - // * int WriteBigEndian(Span) // ? Explicit - // * int WriteLittleEndian(byte[]) // ? Explicit - // * int WriteLittleEndian(byte[], int) // ? Explicit - // * int WriteLittleEndian(Span) // ? Explicit + // * bool TryWriteBigEndian(byte[], out int) + // * bool TryWriteLittleEndian(byte[], out int) + // * int WriteBigEndian(byte[]) + // * int WriteBigEndian(byte[], int) + // * int WriteBigEndian(Span) + // * int WriteLittleEndian(byte[]) + // * int WriteLittleEndian(byte[], int) + // * int WriteLittleEndian(Span) // * IBinaryNumber // * bool IsPow2(TSelf) // * TSelf Log2(TSelf) - // * IComparable // Existing - // * int CompareTo(object?) // * Existing - // * int CompareTo(TSelf) // * Existing - // * IEquatable // Existing - // * bool Equals(TSelf) // * Existing // * IFormattable // Existing // * string ToString(string?, IFormatProvider?) // * Existing - Explicit // * INumber // * TSelf Clamp(TSelf, TSelf, TSelf) - // * TSelf CopySign(TSelf, TSelf) // ? Explicit + // * TSelf CopySign(TSelf, TSelf) // * TSelf Max(TSelf, TSelf) - // * TSelf MaxNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxNumber(TSelf, TSelf) // * TSelf Min(TSelf, TSelf) - // * TSelf MinNumber(TSelf, TSelf) // ? Explicit - // * TSelf Parse(string, NumberStyles, IFormatProvider?) // ? Explicit - // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // ? Explicit + // * TSelf MinNumber(TSelf, TSelf) + // * TSelf Parse(string, NumberStyles, IFormatProvider?) + // * TSelf Parse(ReadOnlySpan, NumberStyles, IFormatProvider?) // * int Sign(TSelf) - // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit - // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // ? Explicit + // * bool TryParse(string?, NumberStyles, IFormatProvider?, out TSelf) + // * bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, out TSelf) // * INumberBase - // * TSelf Abs(TSelf) // ? Explicit + // * TSelf Abs(TSelf) // * TSelf CreateChecked(TOther) // * TSelf CreateSaturating(TOther) // * TSelf CreateTruncating(TOther) - // * bool IsCanonical(TSelf) // ? Explicit + // * bool IsCanonical(TSelf) // * bool IsEvenInteger(TSelf) - // * bool IsFinite(TSelf) // ? Explicit - // * bool IsInfinity(TSelf) // ? Explicit - // * bool IsInteger(TSelf) // ? Explicit - // * bool IsNaN(TSelf) // ? Explicit - // * bool IsNegative(TSelf) // ? Explicit - // * bool IsNegativeInfinity(TSelf) // ? Explicit - // * bool IsNormal(TSelf) // ? Explicit + // * bool IsFinite(TSelf) + // * bool IsInfinity(TSelf) + // * bool IsInteger(TSelf) + // * bool IsNaN(TSelf) + // * bool IsNegative(TSelf) + // * bool IsNegativeInfinity(TSelf) + // * bool IsNormal(TSelf) // * bool IsOddInteger(TSelf) - // * bool IsPositive(TSelf) // ? Explicit - // * bool IsPositiveInfinity(TSelf) // ? Explicit - // * bool IsSignalingNaN(TSelf) // ? Explicit - // * bool IsSubnormal(TSelf) // ? Explicit + // * bool IsPositive(TSelf) + // * bool IsPositiveInfinity(TSelf) + // * bool IsSignalingNaN(TSelf) + // * bool IsSubnormal(TSelf) // * bool IsZero(TSelf) - // * TSelf MaxMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MaxMagnitudeNumber(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitude(TSelf, TSelf) // ? Explicit - // * TSelf MinMagnitudeNumber(TSelf, TSelf) // ? Explicit + // * TSelf MaxMagnitude(TSelf, TSelf) + // * TSelf MaxMagnitudeNumber(TSelf, TSelf) + // * TSelf MinMagnitude(TSelf, TSelf) + // * TSelf MinMagnitudeNumber(TSelf, TSelf) // * bool TryConvertFromChecked(TOther, out TSelf) // * bool TryConvertFromSaturating(TOther, out TSelf) // * bool TryConvertFromTruncating(TOther, out TSelf) @@ -1971,13 +1965,20 @@ namespace System // * bool TryConvertToSaturating(TOther, out TSelf) // * bool TryConvertToTruncating(TOther, out TSelf) // * IParsable - // * TSelf Parse(string, IFormatProvider?) // ? Explicit - // * bool TryParse(string?, IFormatProvider?, out TSelf) // ? Explicit + // * TSelf Parse(string, IFormatProvider?) + // * bool TryParse(string?, IFormatProvider?, out TSelf) // * ISpanFormattable // Existing // * bool TryFormat(Span, out int, ReadOnlySpan, IFormatProvider?) // * Existing - Explicit // * ISpanParsable - // * TSelf Parse(ReadOnlySpan, IFormatProvider?) // ? Explicit - // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) // ? Explicit + // * TSelf Parse(ReadOnlySpan, IFormatProvider?) + // * bool TryParse(ReadOnlySpan, IFormatProvider?, out TSelf) + + // Implicitly Implemented interfaces + // * IComparable // Existing + // * int CompareTo(object?) // * Existing + // * int CompareTo(TSelf) // * Existing + // * IEquatable // Existing + // * bool Equals(TSelf) // * Existing } public struct DateOnly From 7eb3f74ca6ef0778747cb1468cbf69ed6e44aefc Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 10 May 2022 18:55:27 -0700 Subject: [PATCH 35/35] Have INumberConverter expose three methods: ConvertChecked, ConvertSaturating, and ConvertTruncating --- accepted/2021/statics-in-interfaces/README.md | 116 ++++++++++-------- 1 file changed, 64 insertions(+), 52 deletions(-) diff --git a/accepted/2021/statics-in-interfaces/README.md b/accepted/2021/statics-in-interfaces/README.md index 060c558ac..fdf09ae1c 100644 --- a/accepted/2021/statics-in-interfaces/README.md +++ b/accepted/2021/statics-in-interfaces/README.md @@ -1671,10 +1671,14 @@ namespace System.Numerics namespace System.Numerics { public interface INumberConverter - where T : INumber - where U : INumber + where T : INumberBase + where U : INumberBase { - static abstract T Convert(U value); + static abstract T ConvertChecked(U value); + + static abstract T ConvertSaturating(U value); + + static abstract T ConvertTruncating(U value); } } ``` @@ -5164,11 +5168,11 @@ Finally you have types that exist in two parallel assemblies where neither depen The first scenario leads to a design that looks like this. ```csharp -interface INumber - where TSelf : INumber +interface INumberBase + where TSelf : INumberBase { - public static TSelf Create(TOther value) - where TOther : INumber + public static TSelf CreateTruncating(TOther value) + where TOther : INumberBase { if (!TryCreate(value, out TSelf result)) { @@ -5177,14 +5181,14 @@ interface INumber return result; } - static abstract bool TryCreate(TOther value, out TSelf? result) - where TOther : INumber; + static abstract bool TryCreateTruncating(TOther value, out TSelf? result) + where TOther : INumberBase; } -struct Int32 : INumber +struct Int32 : INumberBase { - public static bool TryCreate(TOther value, out int result) - where TOther : INumber + public static bool TryCreateTruncating(TOther value, out int result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5204,10 +5208,10 @@ struct Int32 : INumber } } -struct Int64 : INumber +struct Int64 : INumberBase { - public static bool TryCreate(TOther value, out long result) - where TOther : INumber + public static bool TryCreateTruncating(TOther value, out long result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5230,10 +5234,10 @@ struct Int64 : INumber It runs into the mentioned issues where the conversion fails if `TOther` is unrecognized, such as `BigInteger`: ```csharp -struct BigInteger : INumber +struct BigInteger : INumberBase { - public static bool TryCreate(TOther value, out BigInteger result) - where TOther : INumber + public static bool TryCreateTruncating(TOther value, out BigInteger result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5268,14 +5272,14 @@ There is an additional problem where this actually happens 3 times. Once for `ch The code is used as follows: ```csharp public static TResult Sum(IEnumerable values) - where T : INumber - where TResult : INumber + where T : INumberBase + where TResult : INumberBase { TResult result = TResult.Zero; foreach (var value in values) { - result += TResult.Create(value); + result += TResult.CreateTruncating(value); } return result; @@ -5287,11 +5291,11 @@ public static TResult Sum(IEnumerable values) The second scenario needs to support `TOther` providing a conversion and so the design ends up changing a bit. ```csharp -interface INumber - where TSelf : INumber +interface INumberBase + where TSelf : INumberBase { - public static TSelf Create(TOther value) - where TOther : INumber + public static TSelf CreateTruncating(TOther value) + where TOther : INumberBase { if (!TryCreate(value, out TSelf result)) { @@ -5300,20 +5304,24 @@ interface INumber return result; } - public static bool TryCreate(TOther value, out TSelf? result) - where TOther : INumber + public static bool TryCreateTruncating(TOther value, out TSelf? result) + where TOther : INumberBase { - return TSelf.TryConvertFrom(value, out result) - || TOther.TryConvertTo(value, out result); + return TSelf.TryConvertFromTruncating(value, out result) + || TOther.TryConvertToTruncating(value, out result); } + static bool TryConvertFromTruncating(TOther value, out TSelf result) + where TOther : INumberBase; + static bool TryConvertToTruncating(TSelf value, out TOther result) + where TOther : INumberBase; } -struct Int32 : INumber +struct Int32 : INumberBase { - protected static bool TryConvertFrom(TOther value, out int result) - where TOther : INumber + protected static bool TryConvertFromTruncating(TOther value, out int result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5333,8 +5341,8 @@ struct Int32 : INumber return false; } - protected static bool TryConvertTo(int value, out TOther? result) - where TOther : INumber + protected static bool TryConvertToTruncating(int value, out TOther? result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5355,10 +5363,10 @@ struct Int32 : INumber } } -struct Int64 : INumber +struct Int64 : INumberBase { - protected static bool TryConvertFrom(TOther value, out long result) - where TOther : INumber + protected static bool TryConvertFromTruncating(TOther value, out long result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5378,8 +5386,8 @@ struct Int64 : INumber return false; } - protected static bool TryConvertTo(long value, out TOther? result) - where TOther : INumber + protected static bool TryConvertToTruncating(long value, out TOther? result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5403,10 +5411,10 @@ struct Int64 : INumber This also then allows creating a `Int32` or `Int64` from a `BigInteger`: ```csharp -struct BigInteger : INumber +struct BigInteger : INumberBase { - protected static bool TryConvertFrom(TOther value, out BigInteger result) - where TOther : INumber + protected static bool TryConvertFromTruncating(TOther value, out BigInteger result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5433,8 +5441,8 @@ struct BigInteger : INumber return false; } - protected static bool TryConvertTo(BigInteger value, out TOther? result) - where TOther : INumber + protected static bool TryConvertToTruncating(BigInteger value, out TOther? result) + where TOther : INumberBase { if (typeof(TOther) == typeof(int)) { @@ -5472,8 +5480,8 @@ The same additional problem where this actually happens 3 times. Once for `check The usage code remains the same. ```csharp public static TResult Sum(IEnumerable values) - where T : INumber - where TResult : INumber + where T : INumberBase + where TResult : INumberBase { TResult result = TResult.Zero; @@ -5492,25 +5500,29 @@ This brings us to the third scenario and needing some way to allow conversion be ```csharp interface INumberConverter - where T : INumber - where U : INumber + where T : INumberBase + where U : INumberBase { - static abstract T Convert(U value); + static abstract T ConvertChecked(U value); + + static abstract T ConvertSaturating(U value); + + static abstract T ConvertTruncating(U value); } ``` This would allow the usage code to become: ```csharp public static TResult Sum(IEnumerable values) - where T : INumber - where TResult : INumber + where T : INumberBase + where TResult : INumberBase where TConverter : INumberConverter { TResult result = TResult.Zero; foreach (var value in values) { - result += TConverter.Convert(value); + result += TConverter.ConvertTruncating(value); } return result;