# 高斯整数C#版本

First complex number:  471 + 643i不是高斯素数
Second complex number: 9 + 11i不是高斯素数
The sum of the two numbers: 480 + 654i
The Minus of the two numbers: 462 + 632i
The Product of the two numbers: -2834 + 10968i
The Divide of the two numbers: 56 + 3i,b=True,q=56 + 3i,r=0 + 0i
gcd(112 + 1i,-57 + 79i)=4 + 7i
gcd(112 + 1i,-57 + 79i)=4 + 7i,z5=-1 + -6i,z6=5 + -5i

using System;
using System.Collections.Generic;

public struct Complex
{
public int real;
public int imaginary;
public Complex(int real, int imaginary)
{
this.real = real;
this.imaginary = imaginary;
}
//overload operator(+),added(two Complex objects) and return a Complex type
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
public static Complex operator -(Complex c1, Complex c2)
{
return new Complex(c1.real - c2.real, c1.imaginary - c2.imaginary);
}
public static Complex operator *(Complex c1, Complex c2)
{
return new Complex(c1.real * c2.real - c1.imaginary * c2.imaginary,c1.real * c2.imaginary + c1.imaginary * c2.real);
}
public static Complex operator /(Complex c1, Complex c2)
{
Complex c2c=new Complex(c2.real,-c2.imaginary);
Complex c1c2c=c1*c2c;
int N=Norm(c2);
Complex c1c2=c1*c2c;
double crf=(double)c1c2.real/N;
double cif=(double)c1c2.imaginary/N;
//int cr=crf>0?(int)(crf+0.5):(int)(crf-0.5);
//int ci=cif>0?(int)(cif+0.5):(int)(cif-0.5);
int cr=(int)Math.Floor(crf+0.5);
int ci=(int)Math.Floor(cif+0.5);
return new Complex(cr,ci);
}
// 按范数和辐角主值从小到大排列顺序
public static bool operator < (Complex c1, Complex c2)
{
int norm1=Norm(c1);
int norm2=Norm(c2);
double arg1=Math.Atan2(c1.imaginary,c1.real);
double arg2=Math.Atan2(c2.imaginary,c2.real);
double pi=Math.Atan2(0,-1);
if(arg1<0)
arg1+=2*pi;
if(arg2<0)
arg2+=2*pi;
if(norm1!=norm2)
return norm1<norm2;
else
return arg1<arg2;
}
// 运算符“Complex.operator <(Complex, Complex)”要求也要定义匹配的运算符“>”
public static bool operator > (Complex c1, Complex c2)
{
int norm1=Norm(c1);
int norm2=Norm(c2);
double arg1=Math.Atan2(c1.imaginary,c1.real);
double arg2=Math.Atan2(c2.imaginary,c2.real);
double pi=Math.Atan2(0,-1);
if(arg1<0)
arg1+=2*pi;
if(arg2<0)
arg2+=2*pi;
if(norm1!=norm2)
return norm1>norm2;
else
return arg1>arg2;
}
public static int Norm(Complex a)
{
return (a.real*a.real+a.imaginary*a.imaginary);
}
public static bool divide(Complex a,Complex b,out Complex q,out Complex r)
{
q=a/b;
r=a-q*b;
bool bret=(r.real==0 && r.imaginary==0);
return bret;
}
static void swap(ref Complex a,ref Complex b)
{
Complex t=a;
a=b;
b=t;
}
public static Complex gcd(Complex a,Complex b)
{
Complex x = a, y = b;
if(Norm(x)<Norm(y) )
{
swap(ref x,ref y);
}
while(y.real!=0 || y.imaginary!=0) {
Complex q,r;
bool ret=divide(x,y,out q,out r);
x = y;
y = r;
}
return x;
}
public static Complex extended_gcd(Complex a,Complex b,out Complex x,out Complex y)
{
Complex aa = a, bb = b;
bool swapped = false;
if(Norm(aa)<Norm(bb) )
{
swap(ref aa,ref bb);
swapped = true;
}
Complex xx = new Complex(0,0);
Complex lx = new Complex(1,0);
Complex yy = new Complex(1,0);
Complex ly = new Complex(0,0);
do
{
Complex qq, rr;
bool bret=divide(aa, bb,out qq,out rr);
aa = bb;
bb = rr;
Complex tx = lx-qq*xx;
lx = xx;
xx = tx;
Complex ty = ly-qq*yy;
ly = yy;
yy = ty;
}while(bb.real!=0 || bb.imaginary!=0);
x = lx;
y = ly;
if (swapped)
{
swap(ref x,ref y);
}
return aa;
}
// Override the ToString method to display an complex number in the suitable format:
public override string ToString()
{
return (String.Format("{0} + {1}i", real, imaginary));
}
}

public class numtheory
{
public static bool IsPrime(uint N)
{
if(N==0||N==1)
return false;
int up=Convert.ToInt32(Math.Sqrt((double)N));
for(int i=2;i<=up;i++)
{
if(N%i==0)
return false;
}
return true;
}

/*
高斯整数a+bi是素数当且仅当：
1)a、b中有一个是零，另一个数的绝对值是形如4n+3的素数；
2)a、b均不为零，而a^2+b^2为素数；
*/
public static bool IsPrime(Complex N)
{
int a=Math.Abs(N.real);
int b=Math.Abs(N.imaginary);
if(a==0 && (b+1)%4==0)
return true;
if(b==0 && (a+1)%4==0)
return true;
if(a*b>0 && IsPrime(Convert.ToUInt32(a*a+b*b)))
return true;
return false;
}

public static string is_gausian_prime(bool bret)
{
string strDes=(bret?"是高斯素数":"不是高斯素数");
return strDes;
}

public static void QSort(List<Complex> arr,int startPos,int endPos)
{
Complex z=arr[startPos];
int i=startPos;
int j=endPos;
while(i<j)
{
while(arr[j]>z && i<j)
--j;
arr[i]=arr[j];
while(arr[i]<z && i<j)
++i;
arr[j]=arr[i];
}
arr[i]=z;
if(i-1>startPos)
QSort(arr,startPos,i-1);
if(endPos>i+1)
QSort(arr,i+1,endPos);
}

public static void BubbleSort(List<Complex> a)
{
int n=a.Count;
for(int i=n-1,change=1;i>=1 && change==1;i--)
{
change=0;
for(int j=0;j<i;j++)
if(a[j]>a[j+1])
{
Complex temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
change=1;
}
}
}

// 范数不超过N的高斯整数
public static List<Complex> lessN(int N)
{
List<Complex> L=new List<Complex>();
int n=Convert.ToInt32(Math.Sqrt((double)N));
for(int i=-n;i<=n;i++)
for(int j=-n;j<=n;j++)
{
Complex a;
a.real=i;
a.imaginary=j;
}
//L.Sort();
//QSort(L,0,L.Count-1);
BubbleSort(L);
return L;
}
}

public class ComplexTest
{
static void Main(string[] args)
{
Complex num1 = new Complex(471,643);
Complex num2 = new Complex(9,11);
//Add two Complex objects (num1 and num2) through the overloaded plus operator:
Complex sum_Add = num1 + num2;
Complex sum_Minus = num1 - num2;
Complex sum_Product = num1 * num2;
Complex sum_Divide = num1 / num2;
//Complex q=new Complex();
//Complex r=new Complex();
Complex q,r;
bool b=Complex.divide(num1,num2,out q,out r);
//Print the numbers and the Result using the overriden ToString method:
Console.WriteLine("First complex number:  {0}{1}", num1,numtheory.is_gausian_prime(numtheory.IsPrime(num1)));
Console.WriteLine("Second complex number: {0}{1}", num2,numtheory.is_gausian_prime(numtheory.IsPrime(num2)));
Console.WriteLine("The sum of the two numbers: {0}", sum_Add);
Console.WriteLine("The Minus of the two numbers: {0}", sum_Minus);
Console.WriteLine("The Product of the two numbers: {0}", sum_Product);
Console.WriteLine("The Divide of the two numbers: {0},b={1},q={2},r={3}", sum_Divide,b,q,r);
Complex z1;
z1.real=112;
z1.imaginary=1;
Complex z2=new Complex(-57,79);
Complex z3=Complex.gcd(z1,z2);
Console.WriteLine("gcd({0},{1})={2}", z1,z2,z3);
Complex z5,z6;
Complex z4=Complex.extended_gcd(z1,z2,out z5,out z6);
Console.WriteLine("gcd({0},{1})={2},z5={3},z6={4}", z1,z2,z4,z5,z6);
List<Complex> L=numtheory.lessN(10);
for(int i=0;i<L.Count;i++)
{
Console.WriteLine("第{0}个高斯整数是{1}",i,L[i]);
}