【问题标题】:Fermat's Last Theorem algorithm费马大定理算法
【发布时间】:2013-06-12 12:22:00
【问题描述】:

我正在接受this 费马大定理的定义。

我尝试编写一个算法来验证它是否适用于小值:

#include <iostream>
#include <cmath>
using namespace std;

int main() 
{
    //a^n + b^n = c^n

    int a, b, c, n, count = 0;

    for (n = 3; n < 1000; n++)
        for (a = 1; a < 1000; a++)
            for (b = 1; b < 100; b++)
                for (c = 1; c < 1000; c++)
                {
                    if (a != b && b != c && a != c)
                    {
                        if (pow(a,n) + pow(b,n) == pow(c,n))
                        {
                            cout << "\na: " << a << " b: " << b << " c: " << c << " n: " << n;
                            count++;
                        }
                    }
                }

    cout << count << " combinazioni";

}

这是一段输出的屏幕:

这怎么可能?我是否在 C++ 编程中遗漏了一些可能会得到错误结果的“大整数”?

【问题讨论】:

  • 你知道math.stackexchange.com的数学论坛吗?
  • 我认为你想收集经验证据,直到 ℤ 中的某个 n,而不是证明。 @MarcAudet 我认为如果我们抛弃整个证明业务,这仍然是一个溢出问题。
  • @MarcAudet 任何包含代码的问题通常与Mathematics 无关。
  • 暴力证明需要无限长的时间才能完成。
  • 提示:cout &lt;&lt; pow(c, n) &lt;&lt;endl;

标签: c++ algorithm


【解决方案1】:

你的 pow() 函数溢出了;记住int 的大小是有限的。

例如,pow(256, 4) 会在 32 位上溢出,pow(256, 8) 在 64 位上会溢出,即使您使用无符号数据类型。

从技术上讲,int 溢出是未定义的行为,因此,任何事情都可能发生,包括环绕(即返回 0)或 鼻恶魔.

unsigned int 的计算模数为 2,根据标准提高到 WIDTH 的幂;即将始终环绕。

【讨论】:

  • 他可能在这里使用浮点数调用std::pow。这仍然使它成为溢出,但溢出的性质更加复杂。
  • 好点。虽然我有两个整数的 pow() 重载。
  • 不是只有有符号整数的UB吗?
  • 无符号整数没有溢出,根据标准对这些整数进行模 2^WIDTH然而,这里我们有来自pow()double 结果,并且将超出范围的值从浮点类型转换为无符号整数类型会调用未定义的行为,而不是从整数类型。 (cc @harold)(无论如何,这里我们已经签署了整数。)
  • @harold - 你是对的;我已经修改了我的答案。谢谢。
【解决方案2】:

我错过了什么

你是。实际上相当多。让我一一列举。

  1. 类型。并非 C++ 中的所有数字都是整数。特别是pow 的结果不是整数。
  2. 精度。那些不是整数的类型在 C++ 中的精度有限。在数学中,1 和 1.000000000000000000000000000000000000000000000000982 是不同的数字。在您的 C++ 程序中,祝您好运。
  3. 限制。 C++ 中的整数和非整数都限制在它们可以假设的值范围内。 int 类型的变量保证能够保存 -32767 到 32767 之间的数字。许多实现实际上支持的远不止这些,比如 -2147483648 到 2147483647。许多实现有其他类型可以容纳更大范围的数字,例如0到18446744073709551616或有时340282366920938463463374607431768211456甚至115792089237316195423570985008687907853269984665640564039457584007913129639936.(如果你可以采取100位数字的对数在你的头上,你会发现,所有的这些限制是2的幂或东西接近)。为了比较,以927的104中的功率是376957467458457979751155893254582133603833255821602148851832991547421266649046326838345134050350882042675908426098865621401193999321757163912667101283653576225503152314408933435079267041822928198211089834145222519701307017745008621307049171220994632585789166175212394809510781938945415209193278956111609706241。 LI>

【讨论】:

    【解决方案3】:

    int 值被限制为 32 位(包括符号位),因此高值“包裹”超过 2147483647。C/C++ 没有用于任意大值的内置数据类型。

    为了稍微减少问题,您可以使用longunsigned long 类型(64 位平台上的64 位)。如果您使用long long,某些编译器也支持 32 位平台上的 64 位。

    编辑:正如下面的评论中所指出的,这些限制并不同样适用于 C/C++ 的所有实现,但对于您今天将看到的大多数非嵌入式系统,这些是您将要达到的限制见。

    【讨论】:

    • -1 整数类型的实际大小是在 C++ 中定义的实现。特别是,int 的大小并不总是 32 位,long 并不总是大于 int(尽管在 Op 的屏幕截图中显示的 IDE 两者都是如此)。
    • 正确。我本可以更笼统地解释它,但在这个特定问题的上下文中没有区别。据我所知,没有任何实现可以将pow(927, 104) 放入int。不过,感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2012-08-29
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多