Вы можете написать собственную сложную десятичную структуру. То, как я это сделаю, - это посмотреть на System.Numerics.Complex - Struct и скопировать определения, чтобы у вас была такая же функциональность и именование. Вы можете оставить некоторые функции, если они вам не понадобятся, например тригонометрические функции, операторы преобразования или даже полярные координаты.
Я реализовал некоторые функции в коде ниже. Обратите внимание, что вы можете добавить интерфейсы и, возможно, некоторые проверки ввода для функций.
public struct DecComplex
{
// Member variables.
private decimal real;
private decimal imaginary;
// Read-only properties.
public decimal Real { get { return real; } }
public decimal Imaginary { get { return imaginary; } }
// Constructors.
public DecComplex(decimal real, decimal imaginary)
{
this.real = real;
this.imaginary = imaginary;
}
public DecComplex(double real, double imaginary)
{
this.real = (decimal)real;
this.imaginary = (decimal)imaginary;
}
// Arithmetic operators.
public static DecComplex operator -(DecComplex value)
{
return new DecComplex(-value.real, -value.imaginary);
}
public static DecComplex operator +(DecComplex left, DecComplex right)
{
return new DecComplex(left.real + right.real, left.imaginary + right.imaginary);
}
public static DecComplex operator -(DecComplex left, DecComplex right)
{
return new DecComplex(left.real - right.real, left.imaginary - right.imaginary);
}
public static DecComplex operator *(DecComplex left, DecComplex right)
{
return new DecComplex(left.real * right.real - left.imaginary * right.imaginary, left.real * right.imaginary + left.imaginary * right.real);
}
public static DecComplex operator /(DecComplex left, DecComplex right)
{
var denominator = right.real * right.real + right.imaginary * right.imaginary;
var real = (left.real/denominator * right.real + left.imaginary/denominator * right.imaginary);
var imaginary = (left.imaginary/denominator * right.real - left.real/denominator * right.imaginary);
return new DecComplex(real, imaginary);
}
public static DecComplex operator /(decimal left, DecComplex right)
{
var denominator = right.real * right.real + right.imaginary * right.imaginary;
var real = left * right.real/denominator;
var imaginary = - left * right.imaginary/denominator;
return new DecComplex(real, imaginary);
}
// Conversion operators.
public static explicit operator System.Numerics.Complex(DecComplex value)
{
return new System.Numerics.Complex((double)value.Real, (double)value.Imaginary);
}
// Methods.
public static decimal Abs(DecComplex value)
{
return Sqrt(value.real * value.real + value.imaginary * value.imaginary);
}
public static DecComplex Pow(DecComplex value, int exponent)
{
if (exponent == 0)
return new DecComplex(1.0, 0.0);
var result = value;
for (var i = 1; i < exponent; i++)
{
result = result * value;
}
if (exponent < 0)
return 1.0M/result;
else
return result;
}
public override string ToString()
{
return string.Format("({0}; {1})", this.real, this.imaginary);
}
// Sqrt-Method for the decimal class (by SLenik, http://stackoverflow.com/a/6755197/4469336).
public static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
{
if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number");
decimal current = (decimal)Math.Sqrt((double)x), previous;
do
{
previous = current;
if (previous == 0.0M) return 0;
current = (previous + x/previous)/2;
}
while (Math.Abs(previous - current) > epsilon);
return current;
}
}