【问题标题】:Why functions do not give integer overflow为什么函数不给出整数溢出
【发布时间】:2017-12-10 12:10:59
【问题描述】:

我用 C++ 和 Pascal 编写了函数,可以给我第 n 个斐波那契数。正如预期的大 n 值(n>92,因为即使 f(93) > 2^63+1) 我得到的结果也不正确。
但是当我将它们比较相同的 n 时,我会在两种语言中得到相同的结果。

这与我会得到一些随机数的想法相反。
我想知道为什么我得到相同的结果以及为什么我一开始没有得到整数溢出。

谁能给我解释一下?

代码:

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

long long fibo(int n){
    long long a1,a2,pom;
    int i=1;
    a1 = 0; a2 = 1;
    while(i<=n){
        pom = a2;
        a2 = a1 + a2;
        a1 =  pom;
        i++;
    }
    return a1;
}

int main(){
    int n;
    cin >> n;
    cout << "Function: "<< setprecision(50) << fibo(n) << endl;
}

Program AddNums(output);
function fibo(n:integer):int64;
    var
        a1,a2,pom:int64;
        i:integer;
    begin
        a1:=0;a2:=1;i:=1;
        while(i<=n)do
            begin
                pom:= a2;
                a2:= a1 + a2;
                a1:= pom;
                inc(i);
            end;
        fibo:=a1;
    end;
var
    n:integer;
begin
     readln(n);
    writeln(fibo(n));
end.

【问题讨论】:

  • 什么是整数溢出?恐怕C++中没有这样的东西。
  • 听起来你不太明白整数溢出是如何工作的——当溢出发生时,结果是不正确的,但不是随机
  • 对于给定的CPascal,我得到了相同的结果。正如这里的答案所说,不能保证您的一个或两个编译器都使用模算术。有关编译器和平台的信息有助于解决此类问题。
  • @user0042 - 不过,标准确实谈到了它。
  • 使用模运算可以计算结果。哪一个有偏差?

标签: c++ function pascal fibonacci


【解决方案1】:

未定义的结果不一定是随机。当你在相同的平台上使用相同的初始条件进行相同的计算时,即使结果不正确,也会得到相同的结果。

在您的情况下,Pascal 和 C++ 程序使用相同的底层硬件,具有相同的 int64long long 表示,并且它们指示该硬件对开始相同的数字执行相同的数学运算序列。因此,它们确实到达了相同的数字,代表这一系列操作的最终结果。

结果仍然是不确定的,因为如果你在不同的平台上运行相同的计算,甚至在相同的平台上但使用不同的编译器设置,你可能会得到完全不同的错误结果。

【讨论】:

  • “它们指示硬件对开头相同的数字执行相同的数学运算序列”——如果编译器生成相同的二进制代码,那将是非常令人惊讶的。结果很可能会有所不同,因为编译器在某些时候采用了不同的方法。
  • @Potatoswatter 我试图非常小心地措辞以避免给人一种错误的印象,即来自不同语言的编译器会以某种方式得到相同的二进制代码。数学运算的顺序(a1a2 的加法)将是相同的,而围绕“有效负载”加法序列的其余代码(即循环控制、增量和赋值)几乎肯定会不同.
  • 不同的结果只能来自不同的计算,来自编译器应用的不同推理。例如,在打印检查是否有否定结果时,可以内联和删除。
【解决方案2】:

首先是 (2^63 - 1) 而不是 (2^63 + 1)。

当一个数字溢出时,它会在封闭的数字“循环”中寻找下一个值。

假设它以 0 开头并以 8 结尾,所以如果你的 var 值为 8,而你 ++ 它,那么它将为 0。

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多