C#中的模块化立方体

Haz*_*ior 4 c# algorithm

我很难解决这个问题:

对于正数n,将C(n)定义为整数x的数,其中1 <x <n且x ^ 3 = 1 mod n.

当n = 91时,x有8个可能的值,即:9,16,22,29,53,74,79,81.因此,C(91)= 8.

求出正数n <= 10 ^ 11的总和,其中C(n)= 242.

我的代码:

double intCount2 = 91;
double intHolder = 0;

for (int i = 0; i <= intCount2; i++)
{
    if ((Math.Pow(i, 3) - 1) % intCount2 == 0)
    {
        if ((Math.Pow(i, 3) - 1) != 0)
        {
            Console.WriteLine(i);
            intHolder += i;
        }
    }
}
Console.WriteLine("Answer = " + intHolder);
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

这适用于91但是当我输入任意数量很多的0时,它给了我很多答案,我知道这是错误的.我认为这是因为它非常接近于0,它只是舍入到0.有什么方法可以看出某些东西是否正好是0?或者我的逻辑错了?

我知道我需要一些优化来提供及时答案,但我只是想让它产生正确的答案.

Eri*_*ert 13

让我将您的问题概括为两个问题:

1)这个程序有什么特别的错误?

2)如何确定程序中的问题所在?

其他人已经回答了第一部分,但总结一下:

问题#1:Math.Pow使用双精度浮点数,它只精确到大约15位小数.他们不适合做需要的问题完善涉及精度大整数.如果你尝试计算1000000000000000000 - 1,在双打中,你将得到1000000000000000000,这是15个小数位的准确答案; 这就是我们所能保证的.如果你需要一个完全准确的答案来处理大数,那么使用long来获得低于约100亿亿的结果,或者System.Numerics中的大整数数学类将随下一版本的框架一起提供.

问题2:有更有效的方法来计算模块化指数,这些方法不涉及产生大量数字; 使用它们.

然而,我们在这里得到的是"给人一条鱼"的情况.更好的是教你如何钓鱼; 学习如何使用调试器调试程序.

如果我必须调试这个程序,我要做的第一件事就是重写它,以便沿途的每一步都存储在一个局部变量中:

double intCount2 = 91; 
double intHolder = 0; 

for (int i = 0; i <= intCount2; i++) 
{ 
    double cube = Math.Pow(i, 3) - 1;
    double remainder = cube % intCount2;
    if (remainder == 0) 
    { 
        if (cube != 0) 
        { 
            Console.WriteLine(i); 
            intHolder += i; 
        } 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

现在在调试器中逐步执行它,并举例说明答案是错误的,并查找违反假设的地方.如果你这样做,你会很快发现1000000立方减去1不是99999999999999999,而是1000000000000000000.

所以建议#1:编写代码,以便在调试器中轻松完成,并检查每个步骤,寻找看似错误的代码.

忠告#2:注意安静的唠叨疑虑.当某些东西看起来很狡猾或有点你不理解时,请调查它直到你理解它为止.