高斯整数环学习心得随笔及其实现

本文介绍了一种使用C++实现的高斯整数环运算方法,包括基本运算如加减乘除、取模和最大公约数等,并通过具体代码示例展示了如何进行这些运算。此外,还提供了一些测试用例以验证实现的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高斯整数环学习心得随笔

过些天补上~

代码
  • ==:两个高斯整数相伴,即为相等。
  • 小于和大于:用复数的范数Norm来比较。应用场景举例:高斯整数环的唯一分解定理证明。
  • 整除和取模(带余除法):复数除法的结果是个有理数,但为了方便还是直接用double存了。设两个高斯整数a,b,复数除法结果为a / b = x+yi,则一种可行的取法是round(x)+round(y)*i,这就是整除结果。而g = (x-round(x))+(y-round(y))*i就是带余除法定义中一个可行的“范数小于等于1/2的复数”,g*b即取模结果。具体看代码。
  • gcd:既然有带余除法,直接运行辗转相除法即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 1e3 + 5;
const int mod = 998244353;
int dx[4] = {-1,1,0,0},dy[4] = {0,0,-1,1};

void dbg(){puts("");}
template<typename T, typename... R>void dbg(const T &f, const R &... r) {
    cout << f << " ";
    dbg(r...);
}
template<typename Type>inline void read(Type &xx){
    Type f = 1;char ch;xx = 0;
    for(ch = getchar();ch < '0' || ch > '9';ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9';ch = getchar()) xx = xx * 10 + ch - '0';
    xx *= f;
}
void read(){}
template<typename T,typename ...R>void read(T &x,R &...r){
    read(x);
    read(r...);
}

struct GI;
LL norm(const GI &x);
GI gcd(const GI &x,const GI &y);

struct GI{
    int a,b;
    GI():a(0),b(0){}
    GI(int a,int b):a(a),b(b){}
    //相伴
    bool operator == (const GI &rh) const{
        return a == rh.a && b == rh.b ||
        a == -rh.a && b == -rh.b ||
        a == -rh.b && b == rh.a ||
        a == rh.b && b == -rh.a;
    }
    bool operator < (const GI &rh) const{
        return norm(*this) < norm(rh);
    }
    bool operator <= (const GI &rh) const{
        return norm(*this) <= norm(rh);
    }
    bool operator > (const GI &rh) const{
        return norm(*this) > norm(rh);
    }
    bool operator >= (const GI &rh) const{
        return norm(*this) >= norm(rh);
    }
    GI operator + (const GI &rh) const{
        return {a+rh.a,b+rh.b};
    }
    GI operator - (const GI &rh) const{
        return {a-rh.a,b-rh.b};
    }
    GI operator * (const GI &rh) const{
        return {a*rh.a-b*rh.b,a*rh.b+b*rh.a};
    }
    //整除
    GI operator / (const GI &rh) const{
        double x = 1.0*(a*rh.a+b*rh.b)/norm(rh),y = 1.0*(b*rh.a-a*rh.b)/norm(rh);
        return {round(x),round(y)};
    }
    GI operator % (const GI &rh) const{
        double x = 1.0*(a*rh.a+b*rh.b)/norm(rh),y = 1.0*(b*rh.a-a*rh.b)/norm(rh);
        complex<double> g = {x-round(x),y-round(y)};
        g *= complex<double>(rh.a,rh.b);
        return {round(g.real()),round(g.imag())};
    }
    GI operator %= (const GI &rh){
        GI u = (*this) % rh;
        a = u.a;b = u.b;
        return u;
    }
    friend ostream& operator << (ostream &sm,const GI &x){
        sm << "(" << x.a << "," << x.b << ")";
        return sm;
    }
};
LL norm(const GI &x){return x.a*x.a+x.b*x.b;}
GI gcd(const GI &x,const GI &y){
    return y == GI() ? x : gcd(y,x%y);
}

void test_op(){
    dbg("test_op");
    GI x(4,3),y(3,4);
    assert(GI(4,3) == GI(-4,-3) && GI(4,3) == GI(-3,4) && GI(4,3) == GI(3,-4));
    assert(!(x == y) && x <= y && x >= y);
    GI z(4,4);
    assert(x < z && x <= z && z > x && z >= x);
    assert(x+y == GI(7,7));
    assert(x*y == GI(0,25));
}

//对拍:https://jingyan.baidu.com/article/e75aca8526c6a7142fdac67f.html
void test_div(){
    dbg("test_div");
    GI u = GI(1,8) % GI(-1,5);
    dbg(u);//(-2,-3)
    assert(u == GI(2,3));
    
    GI x(18,5),y(7,5);
    u = x - x / y * y;
    dbg(x / y,u);//x / y = (2,-1), u = (-1,2)
    dbg(x % y);//(-1,2)
    assert(u == x % y);
    dbg(y / u);//(1,-4)
    dbg(y % u);//(0,-1)
    
    x = {112,1};
    y = {-57,79};
    dbg(x / y);//(-1,-1)
    u = x % y;
    dbg(u);//(-24,23)
    assert(u == GI(-24,23));
    
    x %= y;swap(x,y);
    u = x % y;
    dbg(u);//(-8,-14)
    assert(u == GI(-8,-14));
    
    x %= y;swap(x,y);
    u = x % y;
    dbg(u);//(-4,-7)
    assert(u == GI(4,7));
}

void test_gcd(){
    dbg("test_gcd");
    GI g = gcd(GI(18,5),GI(7,5));
    dbg(g);//(0,-1)
    assert(g == GI(0,-1));
    g = gcd(GI(112,1),GI(-57,79));
    dbg(g);//(-4,-7)
    assert(g == GI(4,7));
    g = gcd(GI(32,9),GI(4,11));
    dbg(g);//(0,-1)
    assert(g == GI(1,0));
    g = gcd(GI(11,3),GI(1,8));
    dbg(g);//(1,-2)
    assert(g == GI(1,-2));
    g = gcd(GI(4,5),GI(4,-5));
    dbg(g);//(0,1)
    assert(g == GI(1,0));
}

int main(int argc, char** argv) {
    test_op();
    test_div();
    test_gcd();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值