小数部分最长的循环循环 - 错误或误解

本文关键字:循环 错误 误解 小数部 | 更新日期: 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的有限群,Hi0的子群。然后H的顺序h除以g

所以周期的长度总是prime-1的除数,有时是prime-1,例如7或19。

[1] 对于互质数n 10 的合数,这将是余数模n的组,互质到 n

首先,你不需要除数,你只需要余数。

其次,我会将函数拆分为多个独立的部分,而不是将所有内容都放在一个大方法中:周期长度的长除法/查找独立于其余部分(= 查找最长周期(。

您对i-10 break加上Count是不直观的。为什么不直接使用条件(! digits.Contains(r))while循环?(这需要在循环开始之前将0作为余数放入digits列表中。

这给我们留下了一个更干净的代码,应该可以直接调试。

recurrence = digits.LastIndexOf(m[0]) - digits.IndexOf(m[0]);

当然,resultRecurrence的价值总是i-1的?因为对于形式1/n的一小部分,小数点开始重复,当进行中的除法(第i位(给出与第一次试验除法相同的商余数(i-2500,因此i-1(。

(作为旁注,我可以向您介绍Math.DivRem(。