小数部分最长的循环循环 - 错误或误解
本文关键字:循环 错误 误解 小数部 | 更新日期: 2023-09-27 18:07:24
这是相当'数学'的,但我在这里发帖是因为这是一个欧拉项目的问题,而且我的工作代码可能有错误。
确定十进制扩展中的最长重复周期的问题使用对数解决了这个问题,但我对用简单的蛮力解决感兴趣。更准确地说,我有兴趣了解为什么我的算法和代码没有返回正确的解决方案。
算法很简单:
- 复制一个"长除法",
- 在每一步记录除数和余数
- 当一个除数/余数元组重复时,推断十进制表示将重复。
以下是根据要求的私人字段
private int numerator;
private int recurrence;
private int result;
private int resultRecurrence;
private List<dynamic> digits;
这是代码:
private void Go()
{
foreach (var i in primes)
{
digits = new List<dynamic>();
numerator = 1;
recurrence = 0;
while (numerator != 0)
{
numerator *= 10;
// quotient
var q = numerator / i;
// remainder
var r = numerator % i;
digits.Add(new { Divisor = q, Remainder = r });
// if we've found a repetition then break out
var m = digits.Where(p => p.Divisor == q && p.Remainder == r).ToList();
if (m.Count > 1)
{
recurrence = digits.LastIndexOf(m[0]) - digits.IndexOf(m[0]);
break;
}
numerator = r;
}
if (recurrence > resultRecurrence)
{
resultRecurrence = recurrence;
result = i;
}
}}
当测试整数<10 和 20
所以大概我要么有一个编程错误 - 我找不到 - 要么是一个逻辑错误。
我很困惑,因为它对我来说感觉就像一个乘法群,上面有 p-1 元素。 我确定我错过了一些东西,任何人都可以提供建议吗?
编辑
我不打算包含我的素数代码 - 这无关紧要,正如我在上面解释的那样,我正确识别了i
的值(从内存中它是 983(,但我在获得正确的resultRecurrence
值时遇到了问题。
我很困惑,因为它对我来说感觉就像一个乘法群,上面有 p-1 元素。我确定我错过了一些东西,任何人都可以提供建议吗?
关闭。
对于除 2 和 5(除以 10(之外的所有素数,余数序列由 1 开始并由
remainder = (10 * remainder) % prime
因此,第 k 个余数是 10k(mod 素数(,余数集合形成非零余数模素数组的子群[1]。循环的长度是该子组的阶数,也称为 10 模素数的量级。
非零余数模素数群的阶是prime-1
,费马有一个定理:
设
G
是阶g
的有限群,H
是i
0的子群。然后H
的顺序h
除以g
。
所以周期的长度总是prime-1
的除数,有时是prime-1
,例如7或19。
[1] 对于互质数n
10 的合数,这将是余数模n
的组,互质到 n
。
首先,你不需要除数,你只需要余数。
其次,我会将函数拆分为多个独立的部分,而不是将所有内容都放在一个大方法中:周期长度的长除法/查找独立于其余部分(= 查找最长周期(。
您对i-1
0 break
加上Count
是不直观的。为什么不直接使用条件(! digits.Contains(r))
的while
循环?(这需要在循环开始之前将0
作为余数放入digits
列表中。
这给我们留下了一个更干净的代码,应该可以直接调试。
recurrence = digits.LastIndexOf(m[0]) - digits.IndexOf(m[0]);
当然,resultRecurrence
的价值总是i-1
的?因为对于形式1/n
的一小部分,小数点开始重复,当进行中的除法(第i
位(给出与第一次试验除法相同的商余数(i-250
0,因此i-1
(。
(作为旁注,我可以向您介绍Math.DivRem
(。