Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在我的p-adic算术循环中加入重复检测?_C_Algorithm_Math_Number Systems - Fatal编程技术网

在我的p-adic算术循环中加入重复检测?

在我的p-adic算术循环中加入重复检测?,c,algorithm,math,number-systems,C,Algorithm,Math,Number Systems,我正在实现表示法中数字的算术函数,这是一种形式的。从基本思想来看,我有一个结构和一个构造函数 enum { base = 10 }; /* d[n+m-1] ... d[n+1] d[n] ' d[n-1] ... d[2] d[1] d[0] Sum(i=0..n d[i]*b^i) + Sum(i=n+1..n+m d[i]*b^i/(b^m-1)) */ typedef struct q { int b,n,m,d[]; } *q; 这与论文基本相同,但我对

我正在实现表示法中数字的算术函数,这是一种形式的。从基本思想来看,我有一个结构和一个构造函数

enum { base = 10 };

/*
   d[n+m-1] ... d[n+1] d[n] ' d[n-1] ... d[2] d[1] d[0]

   Sum(i=0..n d[i]*b^i) + Sum(i=n+1..n+m d[i]*b^i/(b^m-1))
 */
typedef struct q { 
    int b,n,m,d[];
} *q; 
这与论文基本相同,但我对索引做了一点修改

/* nb. not defined for LONG_MIN */
q qlong(long i){ 
    if (i<0) return qneg(qlong(-i));
    int m=0;
    int n=i?ceil(log(i)/log(base)):0;
    q z=malloc(sizeof*z + (n+m)*sizeof*z->d);
        z->b=base; z->n=n; z->m=m;
    int j;
    for(j=0; j<n; j++){
        z->d[j] = i % base;
        i /= base;
    }   
    qprint(z);
    return z;
}
/*nb。长_MIN未定义*/
q qlong(long i){
如果(身份证);
z->b=base;z->n=n;z->m=m;
int j;
对于(j=0;jd[j]=i%基数;
i/=基础;
}   
qprint(z);
返回z;
}
利用本文给出的界,我可以估计加法结果的位数

q qadd(q x,q y){
    int m=lcm(x->m,y->m);
    int n=max(x->n,y->n)+m+2;
    int t,c=0;
    q z=malloc(sizeof*z + (n+m)*sizeof*z->d);
        z->b=base; z->n=n; z->m=m;
    int k;
    for(k=0; k<n+m; k++){
        t = qdig(x,k) + qdig(y,k) + c;
        z->d[k] = t % base;
        c = t / base;
    }

    findrepetition(z);
    return z;
}
qadd(qx,qy){
int m=lcm(x->m,y->m);
int n=max(x->n,y->n)+m+2;
int t,c=0;
q z=malloc(sizeof*z+(n+m)*sizeof*z->d);
z->b=base;z->n=n;z->m=m;
int k;
对于(k=0;kd[k]=t%碱基;
c=t/基;
}
金融申诉(z);
返回z;
}
但一旦达到重复状态,这可能会执行不必要的计算,甚至在规范化步骤中会执行更多的计算

在他的著作中,Hehner提出了一种检测重复的算法

void find请求(q z){
int i;
int j;
qprint(z);
对于(i=1;in+z->m-1;i*=2){
对于(j=i+1;jd[j-1]==z->d[i-1]){
z->n=i;
z->m=j-i;
返回;
}
}
}
}
但是我可以将其合并到现有的计算循环中,而不是进行第二次传递吗?我在
qadd
中避免了I和j,因此它们在这些循环中的使用不会与我的使用冲突


这些材料中的一部分之前已发布到,并且有一个链接视频,这是对整个主题的极好介绍。

出于好奇,这只是为了好玩,还是为了实际应用?我认为这种表现的低效性(1/n表示中重复分量的大小将以φ(n)为“most”n的基-b数字的顺序表示)任何实用的东西都会排除这种格式。嗯,两者都有一点。这是一种我希望对其他人有用的格式。我引用的论文的作者肯定认为它是实用的,但事实上它没有被广泛了解或使用,这表明可能存在问题。是的,我认为那些作者可能有点短视考虑到发布日期,可以理解。考虑到<代码> p=2 < /代码>,简单部分<代码> 1/10000000019代码>代码中超过一百亿位来表示(基本上是因为顺序或2模<代码> 10000000019 < /代码>是代码> 10000000018 < /代码>。对于
p=3
p=5
也没有什么好处:在这两种情况下,重复部分都有周期
5000000009
.Hm。在我编写基数转换函数之前,我一直使用p=10作为快捷方式进行测试(我知道这会使除法复杂化,因为10不是素数),但我的计划是使用最大素数<2^32-1。它也会有同样的问题吗?…我假设我选择的任何数字系统都会有一些病态的小角落。但我真的很喜欢这个系统可以处理整数、大整数、有理数和(牺牲循环重复部分)高精度浮点。这将大大简化我在其他解释器中的类型处理。它也会有同样的问题。这不是病理角的情况,而是整个表示方案中的一个系统问题。无论使用什么基
p
,都可以预期大多数形式的分数
m/n
to要求该基底中重复部分的位数的顺序为
phi(n)
(其中
phi
是Euler的toticent函数)。有时它正好是
phi(n)
位数,有时是
phi(n)/2
或更小的数字,有时你会很幸运,重复部分会比
phi(n)短得多
数字。但这些短格是例外,而不是规则。
void findrepetition(q z){
    int i;
    int j;
    qprint(z);
    for(i=1; i<z->n+z->m-1; i*=2) {
        for(j=i+1; j<2*i; j++) {
            if (z->d[j-1]==z->d[i-1]) {
                z->n=i;
                z->m=j-i;
                return;
            }
        }
    }
}