如何编写反向Fibonacci生成器

时间:2016-10-25 23:31:33

标签: java assembly mips

我正在尝试使用MIPS汇编语言编写反向fibonacci生成器,但我真的只是在寻找逻辑,因此我可以理解低级Java或C ++的答案。

我只能使用一个子例程(函数/方法),并且不能存储序列中的任何值。该功能需要计算和打印序列。基本上,我需要使用递归函数。用户将提供斐波那契数字,我需要从该数字开始生成输出并向下移动。我可以访问数字在序列中的第n个位置,无论用户输入什么值。 (即55是第10个斐波纳契数)

我可以使用多个函数调用在C ++中编写代码,但是我很难将其转换为MIPS汇编语言。有没有一种简单的方法可以做到这一点,我错过了?

2 个答案:

答案 0 :(得分:0)

由于天真的Fibonacci计算是递归的,您需要存储数字。

不可能进入第n个F(n)元素计算的中间位置,也不可能得到F(n-2)和F(n-1)个元素,因为这些元素的计算将使用相同的CPU /寄存器,因此必须在F(n-2)/ F(n-1)调用之前存储CPU的中间状态,并在之后恢复,以继续进行F(n)计算。

通常在这种情况下使用堆栈,但无论如何它都是内存并存储中间结果。即使您只将数字保存在CPU寄存器中,它仍然存储值。所以我不确定你在任务描述中的真正限制是什么,它可能是禁止数字存储的一种特定方式,否则它对我没有意义。

要反转过程,例如输出10输入55(这就是你想要的?),你实际上可以从F(1)向上,缓存只有最后两个结果,并查看何时你点击/超限输入值。

让我们将序列定义为:F(n)= F(n-1)+ F(n-2),F(1)= 1,F(2)= 1

算法可以是:

  1. 读取输入
  2. ;初始化计算
  3. 假结果F(n)= 1
  4. F(n-1)= 0
  5. F(n-2)未初始化(在ASM中决定将使用哪个寄存器存储并撰写评论)
  6. n = 1
  7. fibonacciLoop:;主循环
  8. if(input == F(n)),输出“n”作为结果,退出(在ASM中执行“转到outputFound”并在那里写下其余代码,保持fibonacciLoop短)
  9. if(输入< F(n)),输出“输入在n-1和第n个Fib数之间”,退出(在ASM中执行“转到outputBetween”......如上一步骤)
  10. F(n-2)= F(n-1)
  11. F(n-1)= F(n)
  12. F(n)= F(n-1)+ F(n-2)(实际上F(n)+ = F(n-2)重用F(n)旧值)
  13. inc n(增量:n = n + 1)
  14. 转到fibonacciLoop
  15. 尝试在头部验证算法看起来没问题并做你想做的事情,然后在ASM中写入,检查CPU寄存器,如果你可以适合那些中间值([inputnF(n)F(n-1)F(n-2)])进入寄存器(在脑中“分配”它们),然后编写指令以执行每个描述的步骤(我认为大多数都可以实现已经有1-2个CPU指令。)

    该算法当然存储了F(n-2)和F(n-1)值,因此如果按字面意思理解它会破坏您的描述,但您可以将它们保留在寄存器中,而不将其存储在内存中。

    编辑:对于输入“1”,它将始终输出“1”,输出“2”是不可能的。其余斐波那契数字是独一无二的。

    edit2:关于“增量”,刚才我意识到你在谈论MIPS,它类似RISC(精简指令集计算),因此没有专门的+1 inc指令,所以实际上你应该像add r_with_n, r_with_n, #1这样做一般的加法来做“n = n + 1”。

答案 1 :(得分:0)

static void printReverseFib(const int max, const int f1 = 0, const int f2 = 1) {
    if (f2 <= max)
        printReverseFib(max, f2, f1 + f2);
    std::cout << f1 << ' ';
}

int main() {
    printReverseFib(55);
    return 0;
}

55 34 21 13 8 5 3 2 1 1 0