Skip to content

Commit 7181c7f

Browse files
Updating Complex to implement INumberBase and ISignedNumber (#68612)
* Updating Complex to implement INumberBase and ISignedNumber * Adding generic math tests for Complex * Fixing some generic math tests for Complex to match the current behavior around -0 * Update src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs Co-authored-by: Drew Kersnar <dakersnar@me.com> Co-authored-by: Drew Kersnar <dakersnar@me.com>
1 parent b423166 commit 7181c7f

4 files changed

Lines changed: 475 additions & 3 deletions

File tree

src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ namespace System.Numerics
165165
public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? value, out System.Numerics.BigInteger result) { throw null; }
166166
public bool TryWriteBytes(System.Span<byte> destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false) { throw null; }
167167
}
168-
public readonly partial struct Complex : System.IEquatable<System.Numerics.Complex>, System.IFormattable
168+
public readonly partial struct Complex : System.IEquatable<System.Numerics.Complex>, System.IFormattable, System.ISpanFormattable, System.Numerics.IAdditionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IAdditiveIdentity<System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IDecrementOperators<System.Numerics.Complex>, System.Numerics.IDivisionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IEqualityOperators<System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IIncrementOperators<System.Numerics.Complex>, System.Numerics.IMultiplicativeIdentity<System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IMultiplyOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.INumberBase<System.Numerics.Complex>, System.Numerics.ISignedNumber<System.Numerics.Complex>, System.Numerics.ISubtractionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IUnaryNegationOperators<System.Numerics.Complex, System.Numerics.Complex>, System.Numerics.IUnaryPlusOperators<System.Numerics.Complex, System.Numerics.Complex>
169169
{
170170
private readonly int _dummyPrimitive;
171171
public static readonly System.Numerics.Complex ImaginaryOne;
@@ -178,6 +178,11 @@ namespace System.Numerics
178178
public double Magnitude { get { throw null; } }
179179
public double Phase { get { throw null; } }
180180
public double Real { get { throw null; } }
181+
static System.Numerics.Complex System.Numerics.IAdditiveIdentity<System.Numerics.Complex, System.Numerics.Complex>.AdditiveIdentity { get { throw null; } }
182+
static System.Numerics.Complex System.Numerics.IMultiplicativeIdentity<System.Numerics.Complex, System.Numerics.Complex>.MultiplicativeIdentity { get { throw null; } }
183+
static System.Numerics.Complex System.Numerics.INumberBase<System.Numerics.Complex>.One { get { throw null; } }
184+
static System.Numerics.Complex System.Numerics.INumberBase<System.Numerics.Complex>.Zero { get { throw null; } }
185+
static System.Numerics.Complex System.Numerics.ISignedNumber<System.Numerics.Complex>.NegativeOne { get { throw null; } }
181186
public static double Abs(System.Numerics.Complex value) { throw null; }
182187
public static System.Numerics.Complex Acos(System.Numerics.Complex value) { throw null; }
183188
public static System.Numerics.Complex Add(double left, System.Numerics.Complex right) { throw null; }
@@ -209,6 +214,7 @@ namespace System.Numerics
209214
public static System.Numerics.Complex operator +(double left, System.Numerics.Complex right) { throw null; }
210215
public static System.Numerics.Complex operator +(System.Numerics.Complex left, double right) { throw null; }
211216
public static System.Numerics.Complex operator +(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
217+
public static System.Numerics.Complex operator --(System.Numerics.Complex value) { throw null; }
212218
public static System.Numerics.Complex operator /(double left, System.Numerics.Complex right) { throw null; }
213219
public static System.Numerics.Complex operator /(System.Numerics.Complex left, double right) { throw null; }
214220
public static System.Numerics.Complex operator /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
@@ -229,6 +235,7 @@ namespace System.Numerics
229235
public static implicit operator System.Numerics.Complex (uint value) { throw null; }
230236
[System.CLSCompliantAttribute(false)]
231237
public static implicit operator System.Numerics.Complex (ulong value) { throw null; }
238+
public static System.Numerics.Complex operator ++(System.Numerics.Complex value) { throw null; }
232239
public static bool operator !=(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
233240
public static System.Numerics.Complex operator *(double left, System.Numerics.Complex right) { throw null; }
234241
public static System.Numerics.Complex operator *(System.Numerics.Complex left, double right) { throw null; }
@@ -237,17 +244,27 @@ namespace System.Numerics
237244
public static System.Numerics.Complex operator -(System.Numerics.Complex left, double right) { throw null; }
238245
public static System.Numerics.Complex operator -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
239246
public static System.Numerics.Complex operator -(System.Numerics.Complex value) { throw null; }
247+
public static System.Numerics.Complex operator +(System.Numerics.Complex value) { throw null; }
240248
public static System.Numerics.Complex Pow(System.Numerics.Complex value, double power) { throw null; }
241249
public static System.Numerics.Complex Pow(System.Numerics.Complex value, System.Numerics.Complex power) { throw null; }
242250
public static System.Numerics.Complex Reciprocal(System.Numerics.Complex value) { throw null; }
243251
public static System.Numerics.Complex Sin(System.Numerics.Complex value) { throw null; }
244252
public static System.Numerics.Complex Sinh(System.Numerics.Complex value) { throw null; }
245253
public static System.Numerics.Complex Sqrt(System.Numerics.Complex value) { throw null; }
254+
static System.Numerics.Complex System.Numerics.IAdditionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>.operator checked +(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
255+
static System.Numerics.Complex System.Numerics.IDecrementOperators<System.Numerics.Complex>.operator checked --(System.Numerics.Complex value) { throw null; }
256+
static System.Numerics.Complex System.Numerics.IDivisionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>.operator checked /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
257+
static System.Numerics.Complex System.Numerics.IIncrementOperators<System.Numerics.Complex>.operator checked ++(System.Numerics.Complex value) { throw null; }
258+
static System.Numerics.Complex System.Numerics.IMultiplyOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>.operator checked *(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
259+
static System.Numerics.Complex System.Numerics.ISubtractionOperators<System.Numerics.Complex, System.Numerics.Complex, System.Numerics.Complex>.operator checked -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
260+
static System.Numerics.Complex System.Numerics.IUnaryNegationOperators<System.Numerics.Complex, System.Numerics.Complex>.operator checked -(System.Numerics.Complex value) { throw null; }
246261
public static System.Numerics.Complex Subtract(double left, System.Numerics.Complex right) { throw null; }
247262
public static System.Numerics.Complex Subtract(System.Numerics.Complex left, double right) { throw null; }
248263
public static System.Numerics.Complex Subtract(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
264+
public bool TryFormat(System.Span<char> destination, out int charsWritten, System.ReadOnlySpan<char> format, System.IFormatProvider? provider) { throw null; }
249265
public static System.Numerics.Complex Tan(System.Numerics.Complex value) { throw null; }
250266
public static System.Numerics.Complex Tanh(System.Numerics.Complex value) { throw null; }
267+
251268
public override string ToString() { throw null; }
252269
public string ToString(System.IFormatProvider? provider) { throw null; }
253270
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }

src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Diagnostics;
55
using System.Diagnostics.CodeAnalysis;
6+
using System.Globalization;
67
using System.Runtime.CompilerServices;
78

89
namespace System.Numerics
@@ -13,7 +14,11 @@ namespace System.Numerics
1314
/// </summary>
1415
[Serializable]
1516
[TypeForwardedFrom("System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
16-
public readonly struct Complex : IEquatable<Complex>, IFormattable
17+
public readonly struct Complex
18+
: IEquatable<Complex>,
19+
IFormattable,
20+
INumberBase<Complex>,
21+
ISignedNumber<Complex>
1722
{
1823
public static readonly Complex Zero = new Complex(0.0, 0.0);
1924
public static readonly Complex One = new Complex(1.0, 0.0);
@@ -849,5 +854,145 @@ public static explicit operator Complex(decimal value)
849854
{
850855
return new Complex((double)value, 0.0);
851856
}
857+
858+
//
859+
// IAdditionOperators
860+
//
861+
862+
/// <inheritdoc cref="IAdditionOperators{TSelf, TOther, TResult}.op_Addition(TSelf, TOther)" />
863+
static Complex IAdditionOperators<Complex, Complex, Complex>.operator checked +(Complex left, Complex right) => left + right;
864+
865+
//
866+
// IAdditiveIdentity
867+
//
868+
869+
/// <inheritdoc cref="IAdditiveIdentity{TSelf, TResult}.AdditiveIdentity" />
870+
static Complex IAdditiveIdentity<Complex, Complex>.AdditiveIdentity => new Complex(0.0, 0.0);
871+
872+
//
873+
// IDecrementOperators
874+
//
875+
876+
/// <inheritdoc cref="IDecrementOperators{TSelf}.op_Decrement(TSelf)" />
877+
public static Complex operator --(Complex value) => value - One;
878+
879+
/// <inheritdoc cref="IDecrementOperators{TSelf}.op_Decrement(TSelf)" />
880+
static Complex IDecrementOperators<Complex>.operator checked --(Complex value) => --value;
881+
882+
//
883+
// IDivisionOperators
884+
//
885+
886+
/// <inheritdoc cref="IDivisionOperators{TSelf, TOther, TResult}.op_CheckedDivision(TSelf, TOther)" />
887+
static Complex IDivisionOperators<Complex, Complex, Complex>.operator checked /(Complex left, Complex right) => left / right;
888+
889+
//
890+
// IIncrementOperators
891+
//
892+
893+
/// <inheritdoc cref="IIncrementOperators{TSelf}.op_Increment(TSelf)" />
894+
public static Complex operator ++(Complex value) => value + One;
895+
896+
/// <inheritdoc cref="IIncrementOperators{TSelf}.op_CheckedIncrement(TSelf)" />
897+
static Complex IIncrementOperators<Complex>.operator checked ++(Complex value) => ++value;
898+
899+
//
900+
// IMultiplicativeIdentity
901+
//
902+
903+
/// <inheritdoc cref="IMultiplicativeIdentity{TSelf, TResult}.MultiplicativeIdentity" />
904+
static Complex IMultiplicativeIdentity<Complex, Complex>.MultiplicativeIdentity => new Complex(1.0, 0.0);
905+
906+
//
907+
// IMultiplyOperators
908+
//
909+
910+
/// <inheritdoc cref="IMultiplyOperators{TSelf, TOther, TResult}.op_CheckedMultiply(TSelf, TOther)" />
911+
static Complex IMultiplyOperators<Complex, Complex, Complex>.operator checked *(Complex left, Complex right) => left * right;
912+
913+
//
914+
// INumberBase
915+
//
916+
917+
/// <inheritdoc cref="INumberBase{TSelf}.One" />
918+
static Complex INumberBase<Complex>.One => new Complex(1.0, 0.0);
919+
920+
/// <inheritdoc cref="INumberBase{TSelf}.Zero" />
921+
static Complex INumberBase<Complex>.Zero => new Complex(0.0, 0.0);
922+
923+
//
924+
// ISignedNumber
925+
//
926+
927+
/// <inheritdoc cref="ISignedNumber{TSelf}.NegativeOne" />
928+
static Complex ISignedNumber<Complex>.NegativeOne => new Complex(-1.0, 0.0);
929+
930+
//
931+
// ISpanFormattable
932+
//
933+
934+
/// <inheritdoc cref="ISpanFormattable.TryFormat(Span{char}, out int, ReadOnlySpan{char}, IFormatProvider?)" />
935+
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
936+
{
937+
int charsWrittenSoFar = 0;
938+
939+
// We have at least 6 more characters for: (0, 0)
940+
if (destination.Length < 6)
941+
{
942+
charsWritten = charsWrittenSoFar;
943+
return false;
944+
}
945+
946+
destination[charsWrittenSoFar++] = '(';
947+
948+
bool tryFormatSucceeded = m_real.TryFormat(destination.Slice(charsWrittenSoFar), out int tryFormatCharsWritten, format, provider);
949+
charsWrittenSoFar += tryFormatCharsWritten;
950+
951+
// We have at least 4 more characters for: , 0)
952+
if (!tryFormatSucceeded || (destination.Length < (charsWrittenSoFar + 4)))
953+
{
954+
charsWritten = charsWrittenSoFar;
955+
return false;
956+
}
957+
958+
destination[charsWrittenSoFar++] = ',';
959+
destination[charsWrittenSoFar++] = ' ';
960+
961+
tryFormatSucceeded = m_imaginary.TryFormat(destination.Slice(charsWrittenSoFar), out tryFormatCharsWritten, format, provider);
962+
charsWrittenSoFar += tryFormatCharsWritten;
963+
964+
// We have at least 1 more character for: )
965+
if (!tryFormatSucceeded || (destination.Length < (charsWrittenSoFar + 1)))
966+
{
967+
charsWritten = charsWrittenSoFar;
968+
return false;
969+
}
970+
971+
destination[charsWrittenSoFar++] = ')';
972+
973+
charsWritten = charsWrittenSoFar;
974+
return true;
975+
}
976+
977+
//
978+
// ISubtractionOperators
979+
//
980+
981+
/// <inheritdoc cref="ISubtractionOperators{TSelf, TOther, TResult}.op_CheckedSubtraction(TSelf, TOther)" />
982+
static Complex ISubtractionOperators<Complex, Complex, Complex>.operator checked -(Complex left, Complex right) => left - right;
983+
984+
//
985+
// IUnaryNegationOperators
986+
//
987+
988+
/// <inheritdoc cref="IUnaryNegationOperators{TSelf, TResult}.op_CheckedUnaryNegation(TSelf)" />
989+
static Complex IUnaryNegationOperators<Complex, Complex>.operator checked -(Complex value) => -value;
990+
991+
//
992+
// IUnaryPlusOperators
993+
//
994+
995+
/// <inheritdoc cref="IUnaryPlusOperators{TSelf, TResult}.op_UnaryPlus(TSelf)" />
996+
public static Complex operator +(Complex value) => value;
852997
}
853998
}

0 commit comments

Comments
 (0)