Skip to content

Commit d01cabe

Browse files
Updating the generic math interfaces according to the last API review (#67453)
* Create INumberBase and allow Complex to implement it * Move DivRem to only be available for IBinaryInteger * Split apart various floating-point interfaces for better extensibility * Annotate the generic math interfaces to implement on BigInteger and Complex * Moving various generic math interfaces into the System.Numerics namespace * Split various generic math interfaces into their own file for easier discoverability * IParseable -> IParsable * Update ISignedNumber and IUnsignedNumber to be "marker" interfaces * PI -> Pi and IEEERemainder -> Ieee754Remainder * Removing the various TInteger constraints in favor of using int where feasible * Moving IDivisionOperators and ISpanFormattable down to INumberBase * Moving CopySign, IsNegative, MaxMagnitude, and MinMagnitude down to INumber * Create<TOther> -> CreateChecked<TOther> * Updating various generic math tests * Update src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs Co-authored-by: Theodore Tsirpanis <teo@tsirpanis.gr> * Fixing the reference assembly for System.Numerics.Complex * Removing generic math support from System.Numerics.Complex until the trimming issue can be resolved Co-authored-by: Theodore Tsirpanis <teo@tsirpanis.gr>
1 parent 580d556 commit d01cabe

File tree

80 files changed

+4129
-3476
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+4129
-3476
lines changed

src/libraries/System.Numerics.Vectors/tests/Util.cs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -91,62 +91,53 @@ public static T GenerateSingleValue<T>(int min = 1, int max = 100) where T : str
9191
return value;
9292
}
9393

94-
[RequiresPreviewFeatures]
9594
public static T Abs<T>(T value) where T : INumber<T>
9695
{
9796
return T.Abs(value);
9897
}
99-
[RequiresPreviewFeatures]
98+
10099
public static T Sqrt<T>(T value) where T : struct, INumber<T>
101100
{
102-
double dValue = Create<T, double>(value);
101+
double dValue = CreateChecked<T, double>(value);
103102
double dSqrt = Math.Sqrt(dValue);
104103
return T.CreateTruncating<double>(dSqrt);
105104
}
106105

107-
[RequiresPreviewFeatures]
108-
private static TSelf Create<TOther, TSelf>(TOther value)
106+
private static TResult CreateChecked<TOther, TResult>(TOther value)
109107
where TOther : INumber<TOther>
110-
where TSelf : INumber<TSelf>
111-
=> TSelf.Create<TOther>(value);
108+
where TResult : INumber<TResult>
109+
=> TResult.CreateChecked<TOther>(value);
112110

113-
[RequiresPreviewFeatures]
114111
public static T Multiply<T>(T left, T right) where T : INumber<T>
115112
{
116113
return left * right;
117114
}
118115

119-
[RequiresPreviewFeatures]
120116
public static T Divide<T>(T left, T right) where T : INumber<T>
121117
{
122118
return left / right;
123119
}
124120

125-
[RequiresPreviewFeatures]
126121
public static T Add<T>(T left, T right) where T : INumber<T>
127122
{
128123
return left + right;
129124
}
130125

131-
[RequiresPreviewFeatures]
132126
public static T Subtract<T>(T left, T right) where T : INumber<T>
133127
{
134128
return left - right;
135129
}
136130

137-
[RequiresPreviewFeatures]
138131
public static T Xor<T>(T left, T right) where T : IBitwiseOperators<T, T, T>
139132
{
140133
return left ^ right;
141134
}
142135

143-
[RequiresPreviewFeatures]
144136
public static T AndNot<T>(T left, T right) where T : IBitwiseOperators<T, T, T>
145137
{
146138
return left & ~ right;
147139
}
148140

149-
[RequiresPreviewFeatures]
150141
public static T OnesComplement<T>(T left) where T : IBitwiseOperators<T, T, T>
151142
{
152143
return ~left;
@@ -157,43 +148,36 @@ public static float Clamp(float value, float min, float max)
157148
return value > max ? max : value < min ? min : value;
158149
}
159150

160-
[RequiresPreviewFeatures]
161151
public static T Zero<T>() where T : struct, INumber<T>
162152
{
163153
return T.Zero;
164154
}
165155

166-
[RequiresPreviewFeatures]
167156
public static T One<T>() where T : struct, INumber<T>
168157
{
169158
return T.One;
170159
}
171160

172-
[RequiresPreviewFeatures]
173161
public static bool GreaterThan<T>(T left, T right) where T : INumber<T>
174162
{
175163
return left > right;
176164
}
177165

178-
[RequiresPreviewFeatures]
179-
public static bool GreaterThanOrEqual<T>(T left, T right) where T : INumber<T>
180-
{
166+
public static bool GreaterThanOrEqual<T>(T left, T right) where T : INumber<T>
167+
{
181168
return left >= right;
182169
}
183170

184-
[RequiresPreviewFeatures]
185171
public static bool LessThan<T>(T left, T right) where T : INumber<T>
186172
{
187173
return left < right;
188174
}
189175

190-
[RequiresPreviewFeatures]
191176
public static bool LessThanOrEqual<T>(T left, T right) where T : INumber<T>
192177
{
193178
return left <= right;
194179
}
195180

196-
[RequiresPreviewFeatures]
197181
public static bool AnyEqual<T>(T[] left, T[] right) where T : INumber<T>
198182
{
199183
for (int g = 0; g < left.Length; g++)
@@ -206,7 +190,6 @@ public static bool AnyEqual<T>(T[] left, T[] right) where T : INumber<T>
206190
return false;
207191
}
208192

209-
[RequiresPreviewFeatures]
210193
public static bool AllEqual<T>(T[] left, T[] right) where T : INumber<T>
211194
{
212195
for (int g = 0; g < left.Length; g++)

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,26 +2373,38 @@
23732373
</Compile>
23742374
</ItemGroup>
23752375
<ItemGroup>
2376-
<Compile Include="$(MSBuildThisFileDirectory)System\IAdditionOperators.cs" />
2377-
<Compile Include="$(MSBuildThisFileDirectory)System\IAdditiveIdentity.cs" />
2378-
<Compile Include="$(MSBuildThisFileDirectory)System\IBitwiseOperators.cs" />
2379-
<Compile Include="$(MSBuildThisFileDirectory)System\IComparisonOperators.cs" />
2380-
<Compile Include="$(MSBuildThisFileDirectory)System\IDecrementOperators.cs" />
2381-
<Compile Include="$(MSBuildThisFileDirectory)System\IDivisionOperators.cs" />
2382-
<Compile Include="$(MSBuildThisFileDirectory)System\IEqualityOperators.cs" />
2383-
<Compile Include="$(MSBuildThisFileDirectory)System\IFloatingPoint.cs" />
2384-
<Compile Include="$(MSBuildThisFileDirectory)System\IIncrementOperators.cs" />
2385-
<Compile Include="$(MSBuildThisFileDirectory)System\IInteger.cs" />
2386-
<Compile Include="$(MSBuildThisFileDirectory)System\IMinMaxValue.cs" />
2387-
<Compile Include="$(MSBuildThisFileDirectory)System\IModulusOperators.cs" />
2388-
<Compile Include="$(MSBuildThisFileDirectory)System\IMultiplicativeIdentity.cs" />
2389-
<Compile Include="$(MSBuildThisFileDirectory)System\IMultiplyOperators.cs" />
2390-
<Compile Include="$(MSBuildThisFileDirectory)System\INumber.cs" />
2391-
<Compile Include="$(MSBuildThisFileDirectory)System\IParseable.cs" />
2392-
<Compile Include="$(MSBuildThisFileDirectory)System\IShiftOperators.cs" />
2393-
<Compile Include="$(MSBuildThisFileDirectory)System\ISpanParseable.cs" />
2394-
<Compile Include="$(MSBuildThisFileDirectory)System\ISubtractionOperators.cs" />
2395-
<Compile Include="$(MSBuildThisFileDirectory)System\IUnaryNegationOperators.cs" />
2396-
<Compile Include="$(MSBuildThisFileDirectory)System\IUnaryPlusOperators.cs" />
2376+
<Compile Include="$(MSBuildThisFileDirectory)System\IParsable.cs" />
2377+
<Compile Include="$(MSBuildThisFileDirectory)System\ISpanParsable.cs" />
2378+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IAdditionOperators.cs" />
2379+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IAdditiveIdentity.cs" />
2380+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IBinaryFloatingPointIeee754.cs" />
2381+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IBinaryInteger.cs" />
2382+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IBinaryNumber.cs" />
2383+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IBitwiseOperators.cs" />
2384+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IComparisonOperators.cs" />
2385+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IDecrementOperators.cs" />
2386+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IDivisionOperators.cs" />
2387+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IEqualityOperators.cs" />
2388+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IExponentialFunctions.cs" />
2389+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IFloatingPoint.cs" />
2390+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IFloatingPointIeee754.cs" />
2391+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IHyperbolicFunctions.cs" />
2392+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IIncrementOperators.cs" />
2393+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\ILogarithmicFunctions.cs" />
2394+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IMinMaxValue.cs" />
2395+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IModulusOperators.cs" />
2396+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IMultiplicativeIdentity.cs" />
2397+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IMultiplyOperators.cs" />
2398+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\INumber.cs" />
2399+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\INumberBase.cs" />
2400+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IPowerFunctions.cs" />
2401+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IRootFunctions.cs" />
2402+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IShiftOperators.cs" />
2403+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\ISignedNumber.cs" />
2404+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\ISubtractionOperators.cs" />
2405+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\ITrigonometricFunctions.cs" />
2406+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnaryNegationOperators.cs" />
2407+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnaryPlusOperators.cs" />
2408+
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnsignedNumber.cs" />
23972409
</ItemGroup>
23982410
</Project>

src/libraries/System.Private.CoreLib/src/System/Byte.cs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ public readonly struct Byte
3232
public const byte MinValue = 0;
3333

3434
/// <summary>Represents the additive identity (0).</summary>
35-
public const byte AdditiveIdentity = 0;
35+
private const byte AdditiveIdentity = 0;
3636

3737
/// <summary>Represents the multiplicative identity (1).</summary>
38-
public const byte MultiplicativeIdentity = 1;
38+
private const byte MultiplicativeIdentity = 1;
3939

4040
/// <summary>Represents the number one (1).</summary>
41-
public const byte One = 1;
41+
private const byte One = 1;
4242

4343
/// <summary>Represents the number zero (0).</summary>
44-
public const byte Zero = 0;
44+
private const byte Zero = 0;
4545

4646
// Compares this object to another object, returning an integer that
4747
// indicates the relationship.
@@ -314,6 +314,9 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
314314
// IBinaryInteger
315315
//
316316

317+
/// <inheritdoc cref="IBinaryInteger{TSelf}.DivRem(TSelf, TSelf)" />
318+
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right) => Math.DivRem(left, right);
319+
317320
/// <inheritdoc cref="IBinaryInteger{TSelf}.LeadingZeroCount(TSelf)" />
318321
public static byte LeadingZeroCount(byte value) => (byte)(BitOperations.LeadingZeroCount(value) - 24);
319322

@@ -449,21 +452,18 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
449452
// INumber
450453
//
451454

452-
/// <inheritdoc cref="INumber{TSelf}.One" />
453-
static byte INumber<byte>.One => One;
454-
455-
/// <inheritdoc cref="INumber{TSelf}.Zero" />
456-
static byte INumber<byte>.Zero => Zero;
457-
458455
/// <inheritdoc cref="INumber{TSelf}.Abs(TSelf)" />
459-
public static byte Abs(byte value) => value;
456+
static byte INumber<byte>.Abs(byte value) => value;
460457

461458
/// <inheritdoc cref="INumber{TSelf}.Clamp(TSelf, TSelf, TSelf)" />
462459
public static byte Clamp(byte value, byte min, byte max) => Math.Clamp(value, min, max);
463460

464-
/// <inheritdoc cref="INumber{TSelf}.Create{TOther}(TOther)" />
461+
/// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" />
462+
static byte INumber<byte>.CopySign(byte value, byte sign) => value;
463+
464+
/// <inheritdoc cref="INumber{TSelf}.CreateChecked{TOther}(TOther)" />
465465
[MethodImpl(MethodImplOptions.AggressiveInlining)]
466-
public static byte Create<TOther>(TOther value)
466+
public static byte CreateChecked<TOther>(TOther value)
467467
where TOther : INumber<TOther>
468468
{
469469
if (typeof(TOther) == typeof(byte))
@@ -685,17 +685,23 @@ public static byte CreateTruncating<TOther>(TOther value)
685685
}
686686
}
687687

688-
/// <inheritdoc cref="INumber{TSelf}.DivRem(TSelf, TSelf)" />
689-
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right) => Math.DivRem(left, right);
688+
/// <inheritdoc cref="INumber{TSelf}.IsNegative(TSelf)" />
689+
static bool INumber<byte>.IsNegative(byte value) => false;
690690

691691
/// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" />
692692
public static byte Max(byte x, byte y) => Math.Max(x, y);
693693

694+
/// <inheritdoc cref="INumber{TSelf}.MaxMagnitude(TSelf, TSelf)" />
695+
static byte INumber<byte>.MaxMagnitude(byte x, byte y) => Max(x, y);
696+
694697
/// <inheritdoc cref="INumber{TSelf}.Min(TSelf, TSelf)" />
695698
public static byte Min(byte x, byte y) => Math.Min(x, y);
696699

700+
/// <inheritdoc cref="INumber{TSelf}.MinMagnitude(TSelf, TSelf)" />
701+
static byte INumber<byte>.MinMagnitude(byte x, byte y) => Min(x, y);
702+
697703
/// <inheritdoc cref="INumber{TSelf}.Sign(TSelf)" />
698-
public static byte Sign(byte value) => (byte)((value == 0) ? 0 : 1);
704+
public static int Sign(byte value) => (value == 0) ? 0 : 1;
699705

700706
/// <inheritdoc cref="INumber{TSelf}.TryCreate{TOther}(TOther, out TSelf)" />
701707
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -885,10 +891,20 @@ public static bool TryCreate<TOther>(TOther value, out byte result)
885891
}
886892

887893
//
888-
// IParseable
894+
// INumberBase
889895
//
890896

891-
/// <inheritdoc cref="IParseable{TSelf}.TryParse(string?, IFormatProvider?, out TSelf)" />
897+
/// <inheritdoc cref="INumberBase{TSelf}.One" />
898+
static byte INumberBase<byte>.One => One;
899+
900+
/// <inheritdoc cref="INumberBase{TSelf}.Zero" />
901+
static byte INumberBase<byte>.Zero => Zero;
902+
903+
//
904+
// IParsable
905+
//
906+
907+
/// <inheritdoc cref="IParsable{TSelf}.TryParse(string?, IFormatProvider?, out TSelf)" />
892908
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out byte result) => TryParse(s, NumberStyles.Integer, provider, out result);
893909

894910
//
@@ -905,13 +921,13 @@ public static bool TryCreate<TOther>(TOther value, out byte result)
905921
// static byte IShiftOperators<byte, byte>.operator >>>(byte value, int shiftAmount) => (byte)(value >> shiftAmount);
906922

907923
//
908-
// ISpanParseable
924+
// ISpanParsable
909925
//
910926

911-
/// <inheritdoc cref="ISpanParseable{TSelf}.Parse(ReadOnlySpan{char}, IFormatProvider?)" />
927+
/// <inheritdoc cref="ISpanParsable{TSelf}.Parse(ReadOnlySpan{char}, IFormatProvider?)" />
912928
public static byte Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => Parse(s, NumberStyles.Integer, provider);
913929

914-
/// <inheritdoc cref="ISpanParseable{TSelf}.TryParse(ReadOnlySpan{char}, IFormatProvider?, out TSelf)" />
930+
/// <inheritdoc cref="ISpanParsable{TSelf}.TryParse(ReadOnlySpan{char}, IFormatProvider?, out TSelf)" />
915931
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out byte result) => TryParse(s, NumberStyles.Integer, provider, out result);
916932

917933
//
@@ -940,8 +956,5 @@ public static bool TryCreate<TOther>(TOther value, out byte result)
940956

941957
/// <inheritdoc cref="IUnaryPlusOperators{TSelf, TResult}.op_UnaryPlus(TSelf)" />
942958
static byte IUnaryPlusOperators<byte, byte>.operator +(byte value) => (byte)(+value);
943-
944-
// /// <inheritdoc cref="IUnaryPlusOperators{TSelf, TResult}.op_CheckedUnaryPlus(TSelf)" />
945-
// static byte IUnaryPlusOperators<byte, byte>.operator checked +(byte value) => checked((byte)(+value));
946959
}
947960
}

0 commit comments

Comments
 (0)