确定给定的整数是否是C中Fibonacci序列的元素而不使用float

时间:2018-05-25 09:54:41

标签: c floating-point integer fibonacci integer-division

我最近接受了一次采访,在那里我失败了,最后被告知没有足够的经验为他们工作。

该职位是嵌入式C软件开发人员。目标平台是某种非常简单的32位架构,这些处理器不支持浮点数及其操作。因此,不能使用double和float数字。

任务是为这个架构开发一个C例程。此取一个整数并返回是否为斐波纳契数。但是,从内存中执行期间只允许使用的额外1K临时空间。这意味着:即使我模拟了非常大的整数,我也不能只是建立序列并进行交互。

据我所知,正整数恰好是斐波那契数,如果

之一
  

(5n ^ 2)+ 4

  

(5n ^ 2) - 4

是一个完美的广场。因此我回答了这个问题:这很简单,因为例程必须确定是否是这种情况。

他们当时回应:在当前目标体系结构上,不支持类似浮点运算,因此使用stdlib的sqrt函数无法检索平方根数。还有人提到,由于架构的局限性,分区和模数等基本操作也可能不起作用。

然后我说,好吧,我们可以构建一个方形数到256的数组。然后我们可以迭代并将它们与公式给出的数字进行比较(见上文)。他们说:这是一个糟糕的方法,即使它会起作用。因此他们不接受这个答案。

最后我放弃了。因为我没有其他想法。我问,解决方案是什么:他们说,不会被告知;但建议我自己去尝试一下。我的第一种方法(2公式)应该是关键,但平方根可以替代地完成。

我在家里搜索了很多,但从未找到任何“替代”平方根计数器算法。允许任何地方使用浮动数字。

对于除法和模数等操作,可以使用所谓的“整数除法”。但是什么用于平方根?

即使我没有通过面试测试,这对我来说也是一个非常有趣的话题,可以在不允许浮点运算的架构上工作。

因此我的问题:

  1. 如何模拟浮点数(如果只允许使用整数)?
  2. 对于上述问题,C中可能存在什么样的灵魂?欢迎使用代码示例。

2 个答案:

答案 0 :(得分:2)

此类访谈的目的是了解您如何处理新问题。如果您碰巧已经知道答案,那无疑是您的功劳,但它并没有真正回答这个问题。面试官有趣的是看着你解决这些问题。

出于这个原因,面试官通常会增加额外的限制,试图带你离开你的舒适区,看看你是如何应对的。

我认为你知道关于识别斐波纳契数的事实是很好的。没有咨询维基百科我就不会知道。这是一个有趣的事实,但它确实有助于解决问题吗?

显然,有必要计算5n²±4,计算平方根,然后验证其中一个是整数。通过以足够的精度访问浮点实现,这不会太复杂。但那精度是多少?如果n可以是任意32位有符号数,那么显然不适合32位。实际上,5n²+4可能大到65位,不包括符号位。这远远超出double(通常为52位)甚至long double的精度(如果可用)。因此计算精确的平方根将是有问题的。

当然,我们实际上并不需要精确的计算。我们可以从近似开始,将其平方,并查看它是否比5n²小四或四。而且很容易看出如何计算一个好的猜测:它将非常接近n×√5。通过使用良好的预先计算的√5近似,我们可以轻松地进行此计算,而无需浮点,无需除法,也无需使用sqrt函数。 (如果近似值不准确,我们可能需要向上或向下调整结果,但使用标识(n+1)² = n²+2n+1很容易;我们有后,我们可以计算(n+1)²只添加。

我们仍然需要解决精度问题,因此我们需要一些处理66位整数的方法。但是我们只需要实现正整数的加法和乘法,比完全成熟的bignum包简单得多。实际上,如果我们能够证明我们的平方根估计足够接近,我们就可以安全地进行验证模2³¹。

因此,分析解决方案可以使用,但在深入研究之前,我们应该问一下它是否是最佳解决方案。对于次优编程而言,一种非常普遍的关注是紧紧抓住你提出的第一个想法,即使它的复杂性变得越来越明显。这将是面试官想要了解的事情之一:当您获得新信息或新要求时,您有多灵活。

那么有什么其他方法可以知道n是否是斐波纳契数。一个有趣的事实是,如果nFib(k),则klogφ(k×√5 + 0.5)的最低点。由于logφ很容易从log2计算,而k可以通过简单的按位运算来近似,我们可以尝试找到O(log k)的近似值并使用经典{{1}进行验证计算Fib(k)的递归。上述所涉及的数字都不大于32位有符号类型的容量。

更简单地说,我们可以在一个循环中运行Fibonacci系列,检查我们是否达到了目标数。只需要47个循环。或者,这些47个数字可以通过二进制搜索进行预先计算和搜索,使用的距离远远小于允许的1k字节。

答案 1 :(得分:1)

编程职位的面试官不太可能测试斐波纳契数列特定属性的知识。因此,除非他们提出要测试的属性,否则他们正在研究候选人对这种性质的问题的方法以及他们对算法的一般知识。值得注意的是,迭代一个正方形表的概念在几个方面是一个糟糕的反应:

  • 至少应该首先考虑二进制搜索查找表格。还可以提出一些计算查找方法供讨论,例如使用find-first-set-bit指令索引到表中。
  • 哈希可能是另一个值得考虑的想法,特别是因为可能会构建一个有效的自定义哈希。
  • 一旦我们决定使用表格,斐波那契数字的直接表格可能比广场表更有用。