【问题标题】:Translating two C++ functions to Pascal将两个 C++ 函数转换为 Pascal
【发布时间】:2016-04-22 08:56:56
【问题描述】:

我似乎无法理解为什么我的翻译没有给出预期的结果。这是 C++ 源代码:

#include <stdio.h>

int minint(int candidate = -1) {
  if (candidate - 1 >= 0)
    return candidate;
  for (int stride = -1, stride2 = 2*stride; ; stride = stride2, stride2 += stride2)
    if (stride2 >= 0 || candidate + stride2 >= 0)
      return minint(candidate + stride);
}

int maxint(int candidate = 1) {
  if (candidate + 1 <= 0)
    return candidate;
  for (int stride = 1, stride2 = 2*stride; ; stride = stride2, stride2 += stride2)
    if (stride2 <= 0 || candidate + stride2 <= 0)
      return maxint(candidate + stride);
}

int main() {
  (void) printf("Max int is %d\n", maxint());
  (void) printf("Min int is %d\n", minint());
  return 0;
}

打印出来:

Max int is 2147483647
Min int is -2147483648

这是 Pascal 代码(使用 Free Pascal 编译):

program Translation;

function minint (candidate : Longint) : Longint;
    var stride, stride2 : Longint;
    var bool : Boolean;
    begin
        bool := false;
        if (candidate - 1) >= 0 then
        begin
            bool := true;
            minint := candidate;
        end;
        if (bool = false) then
        begin
            stride := -1;
            stride2 := 2*stride;
            while (stride2 < 0) and (candidate + stride2 < 0) do
            begin
                stride := stride2;
                stride2 += stride2;
            end;
            minint := minint(candidate + stride)
        end;
    end;

function maxint (candidate : Longint) : Longint;
    var stride, stride2 : Longint;
    var bool : Boolean;
    begin
        bool := false;
        if (candidate + 1) <= 0 then
        begin
            bool := true;
            maxint := candidate;
        end;
        if (bool = false) then
        begin
            stride := 1;
            stride2 := 2*stride;
            while (stride2 > 0) and (candidate + stride2 > 0) do
            begin
                stride := stride2;
                stride2 += stride2;
            end;
            maxint := minint(candidate + stride)
        end;
    end;

begin
    writeln(maxint(1));
    writeln(minint(-1));
end.

由于某种原因打印:

1073741825
2147483647

非常非常奇怪。 'maxint' 值大约是所需值的一半,而 'minint' 值是正数(实际上,它应该是 'maxint' 值)。

我错过了什么?请记住,我被禁止使用定序器(即,诸如 Exit 之类的命令 - 因此是布尔值)和默认参数。

【问题讨论】:

  • 你的 C++ 版本看起来也很错误......
  • 看起来 C++ 代码在有符号整数上使用带有算术上溢/下溢的未定义行为(我对此并不确定——充其量是扭曲的代码)。帕斯卡会做不同的事情。
  • 是的,那个 C++ 版本是错误的。它可能适用于某些编译器。 (甚至可能是大多数。)但是至少有两个当前主要的编译器以一种绝对不会做你想做的事情的方式编译它。使用 GCC,它会被编译为无限循环。使用 clang,打印的 max int 为负数,打印的 min int 为正数。 @JonathanLeffler 它拥有的 UB 确实是有符号整数溢出。
  • 感谢您的快速回复。可悲的是,C++ 代码是我提供的。这是给定的。试图改变它是没有意义的,尽管我完全同意它是非常模糊的。那里有一个等效的 Pascal 代码。应该主要是基于这些破碎的C++函数。有什么办法可以克服原始功能的故意缺陷?
  • it is highly obscure 这不仅晦涩难懂,而且肯定是错误的,即使它使用编译器在您的计算机上打印了正确的结果。虽然这对你没有帮助,但它说明了你的老师(等等)......

标签: c++ pascal freepascal translate


【解决方案1】:

这,IMO 相当直译(但不使用 BreakContinueExit)对我有用(注意:Delphi,不是 FPC,但我猜 FPC 中有兼容模式):

{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
function minint(candidate: Integer = -1): Integer;
var
  stride: Integer;
  stride2: Integer;
begin
  if candidate - 1 >= 0 then
    minint := candidate
  else
  begin
    stride := -1;
    stride2 := 2 * stride;
    while (stride2 < 0) and (candidate + stride2 < 0) do
    begin
      stride := stride2;
      stride2 := stride2 + stride2;
    end;
    minint := minint(candidate + stride);
  end;
end;

它产生以下输出:

Min int is -2147483648

我没有翻译 maxint,但我想你可以自己做。

看起来很像你的翻译(但没有布尔)。

【讨论】:

    【解决方案2】:

    不要依赖 C++ 中的下溢/上溢行为。它是未定义的。
    相反,请使用限制库来确定您的整数大小限制。

    #include <iostream>
    #include <limits>
    
    int main() {
        std::cout << std::numeric_limits<int>::max() << '\n';
        std::cout << std::numeric_limits<int>::min() << '\n';
        return 0;
    }
    

    在 Pascal 中,LongInt 具有固定大小。
    您可以依赖它长 4 个字节。


    关于您的 Pascal 代码,您的“maxint”函数中有错字。

    行:

    maxint := minint(candidate + stride)
    

    应该是:

    maxint := maxint(candidate + stride)
    

    【讨论】:

    • (其实问题是关于int
    • 谢谢,但我的任务不是编写 C++ 代码,也不是查找类型的数字限制。我被要求将给定的 C++ 代码翻译成 Pascal。如有任何帮助找到我的翻译错误,我们将不胜感激。
    • @deviantfan 好的,更改为 int。 pascal 示例使用 LongInt 而不是 Integer,这似乎不协调。
    • @JeanFrancoisClout C++ 代码返回固定值。找到这些值,您就可以准确地将其转换为 Pascal 单行。或者你想让你的 Pascal 代码根据使用的编译器和优化级别表现出相同的不可预测的行为? (我不是因为这个坏问题责备你,我知道你无法控制它,但这仍然不能使它成为一个好问题。)
    • @JeanFrancoisClout 这个任务很荒谬,因为他们在 C++ 中给了你一个未定义的算法,而你永远不想在 Pascal 中这样做。尽管如此,您的实际问题在于您调用 maxint := minint(candidate + stride) 而不是 maxint := maxint(candidate + stride) 的“maxint”函数。这是固定版本:ideone.com/8itUZg
    猜你喜欢
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2011-12-24
    相关资源
    最近更新 更多