Floating point 没有浮点的MCU如何找到sqrt(2)?

Floating point 没有浮点的MCU如何找到sqrt(2)?,floating-point,embedded,Floating Point,Embedded,我在上次面试中被问到这个问题,我期待着它再次出现。采访对象是为嵌入式系统编程的固件工程师。可用于这些应用程序的微处理器和微控制器通常不是非常强大,而较简单的微处理器和微控制器没有进行浮点计算的能力,内部没有乘法器或除法器 那么这个问题的可能答案是什么呢?如果不动点算法与此有关呢 有没有可能用牛顿-拉斐逊法来做这个计算?如何计算?ENIAC仅使用加法和减法求平方根。 它基于这样一个公式:前n个奇数整数的和是n的平方 要计算m的平方根,请找到最小整数n,使前n个奇数整数之和超过m。这可以通过从m中减

我在上次面试中被问到这个问题,我期待着它再次出现。采访对象是为嵌入式系统编程的固件工程师。可用于这些应用程序的微处理器和微控制器通常不是非常强大,而较简单的微处理器和微控制器没有进行浮点计算的能力,内部没有乘法器或除法器

那么这个问题的可能答案是什么呢?如果不动点算法与此有关呢


有没有可能用牛顿-拉斐逊法来做这个计算?如何计算?

ENIAC仅使用加法和减法求平方根。 它基于这样一个公式:前n个奇数整数的和是n的平方


要计算m的平方根,请找到最小整数n,使前n个奇数整数之和超过m。这可以通过从m中减去连续的奇数整数来实现,直到得到负结果。如果n是最小的整数,那么m-1+3+5+…+2n-1<0然后n-1^2是的,你可以用牛顿-拉斐逊来计算平方根。通常是这样做的:

让x为数字。我们将首先近似1/sqrtx,然后将其乘以x得到x/sqrtx,即sqrtx

给定x,创建1/sqrtx的粗略估计值。通常,这是通过一个小的查找表来完成的,但是任何合理的估计都足以包括1。将初始估计值称为e0

根据需要多次重复此步骤:从当前估计值ei创建一个新估计值ei+1=1/2·ei·3−x·ei2。通常,所需的步数可以通过数值分析、1/sqrtx初始估计的质量以及应用程序所需的精度预先确定

最后,返回sqrtx估算的最后一个ei·x

该序列收敛速度非常快,通常用于计算平方根。您可以从开始了解如何导出平方根倒数的序列。还请注意,它不使用除法,这通常是一个缓慢的操作

对于这些计算,您将使用定点,因为您需要比整数提供的精度更高的精度,但浮点不可用


本质上,面试官是在试探你是否有在嵌入式处理器上使用数值算法的经验。

像以往任何面试问题一样,聪明的回答是提出反问题。旨在澄清和消除问题歧义的聪明问题表明,你可以思考,而不是简单地说出公认的智慧或教条,还将缩小问题的范围,使你的答案更可能适用。在这种情况下,没有浮点的MCU和不使用浮点的软件实现之间可能存在区别。如果是后者,那么定点肯定是相关的,但在许多应用程序中,根可能就足够了——您可能会问这个问题,但在这种情况下isqrt2==1似乎不太合适。对于前者,这种情况并不排除使用浮点

通常情况下,在嵌入式系统中使用浮点时的问题是缺少浮点单元FPU,从而导致软件中实现的浮点操作速度慢得多,确定性差得多。缺少FPU,甚至没有硬件整数乘法或除法,并不排除使用浮点运算,这只是意味着这种运算速度要慢得多,需要更大的代码空间

在大多数系统上,即使没有硬件浮点支持,标准库数学函数仍将由软件浮点支持,并且可以正常使用-即使在8位系统上-但不要期望性能。在某些情况下,性能受到影响,并且库实现的不确定性可能会阻止它的使用,在这种情况下,有许多算法返回更快或更确定的性能

如果要根的值很大,且整数结果足够精确,则纯整数解将是最快的,但是对于一般情况,有许多解,其中Newton Raphson是一个,但不太可能是最优的-这是平方根算法的气泡排序;之所以使用它,是因为它易于教学和理解,而不是因为它的性能

使用定点是一种可能,但不是一种内在的数据类型,代码可能会变得不那么容易编写和调试。我用的是a;它是用C++编写的,定义了固定类;C++的函数和运算符重载能力意味着大多数浮点数代码可以简单地通过替换浮点或双固定来移植。在ARM处理器上,固定类的执行速度大约是软件浮点类的五倍。然而,Anthony的sqrt算法可以改进,因为我已经介绍了descr IbAd基于本文的实现-该文章中的代码是在C中,因此通常更适用于C++是不可用或不实用的,尽管这是不同的论点!p> Jack Crenshaw在他的书中用了整整一章来讨论sqrt函数,他从一个幼稚的Newton Raphson实现开始,并逐渐对其进行了改进。他还提出了一个整数解,但有趣的是,它不是定点解。杰克书中的一些内容已经出现在他的期刊文章中;例如,他对儿童的治疗

无论如何,我可以回答以下问题:

我将评估标准库软件浮点性能、精度和对代码大小的影响,并且只有当我发现它不适合应用程序要求时,我会考虑使用已建立的算法和可能的定点算法进行优化的解决方案。


请注意我使用的术语“已建立的算法”;它有效地避免了我可能不知道或不记得任何特定算法的名称这一事实,我真正想说的是,我不知道什么算法是合适的,但我没有愚蠢到重新发明轮子,因为我不可能想出比目前还没有的更好的算法,通过仔细的研究和评估,如果可行的话,我会达到预期的结果。如果一位受访者给出了这个答案,并在面试前提出了一些聪明的问题,我会觉得这是完全可以接受的。当然,面试官可能没有你聪明,他可能有一个他认为正确的答案;你可能不想在一个有这种教条式反应的组织中工作。面试是一个双向的过程——你面试的目的是想看看你是否愿意为公司提供服务。

hmm,我想这个问题已经在这里了。我还没有看到它特别要求嵌入式系统。关于如何找到一个数字的sqrt,有一些技巧,但在我介绍的要点之后,这不是一个问题。我只是想知道为什么我们需要浮点。我们也有固定点,在我看来这已经足够了。我从来都不知道定点,因为我只听说过浮点数。直到我对面试问题的主题做了一些研究之后,我才意识到还有一种叫做定点数字的东西。@quantum231:为什么我们有浮点是一个新问题的主题。定点算法在有限域中可能有用,其中所涉及的数字规模保持在一个狭窄的范围内,并且事先已知。浮点运算非常灵活,可以处理从非常小到非常大的大范围数字,并且减轻了程序员跟踪范围和防止溢出直到异常大的负担。它在物理学中很有用,无论是科学还是游戏物理学,工程学,以及许多其他领域。@quantum231:定点确实经常是足够的,在没有浮点硬件支持的情况下,定点速度更快。然而,虽然它完全适合sqrt2,但固定的sqrt算法必然会失去一些精度,因此对于非常小的值的根,您可能最终会出现严重的错误。浮点更好地处理更大范围的值,而定点通常是范围和精度之间的折衷。另一方面,浮点运算同样会对包含非常大和非常小的值的表达式产生很大的错误。@Clifford-我已经实现了巴比伦式的方法,只计算平方根整数,并将其转换为浮点运算,以较少的迭代次数精确到小数点后6位。重大错误需要取非常小的数字的平方根。对于大多数算法来说,您需要在速度和精度之间进行权衡。本机使用浮点的功能只允许您在一种实现或另一种实现之间进行选择。仅仅通过使用FPU并不能改善结果。另请参见。
a - 1 <= 2*sqrt(m) < a + 1
(a - 1)/2 <= sqrt(m) < (a + 1)/2