2017-05-19 39 views
0

我正在Atmel Studio中使用ATmega328P,我必须制作一个函数/算法,它需要一个8位数并计算它的平方根。结果必须在两个寄存器中给出,一个用于整数部分,另一个用于小数部分。Atmel工作室组件:8位数的平方根

我在想这个问题:根必须在给定数字和0(或1)之间。因此,我会将lsr(除以2)检查它是否更大,更小或相等,然后再以更精确的方式再次尝试,因此它会变得越来越精确。

问题是整数将不正确,我不知道如何把它放到代码中,因为我是一个新的程序集。我也可以发布我迄今为止所做的。

感谢您的任何建议和帮助。

+3

256字节长度如何查找包含结果的表格? (呃,更像是512B长,因为小数部分......是定点数学8:8?我猜)(如果你只有256B的小数部分,整个部分可以简单地+缓慢地完成一个循环) – Ped7g

+0

不幸的是,这是和分配,我必须计算它,否则这将是一个可行的选择,但感谢您的意见。 –

+0

虽然我会这样做作为最后的手段,如果我不明白。 (你建议制作一个程序,将插入的数字与256个结果进行比较,如果发现它是正确的,则结束) –

回答

0

只是为了完整性(或无用的表示),以下是如何使用整数完成任务,无需乘法,通过线性搜索(应该在大多数情况下为0-15个值仍然更快,二进制搜索与乘法)。

root = -1 
square = 0 
addValue = 1 
while (square <= input) { 
    square += addValue 
    addValue += 2 
    ++root 
} 
; here root == trunc(sqrt(input)) 

所以,如果你不需要小数部分,这将是足够的,或者如果你将被允许使用至少256B长LUT的小数部分,与此一起。

用8位整数寄存器写适当的十进制sqrt实际上是一些工作,我不会从你身上带走所有的乐趣。 :P ..

检查各种算法,不要忘记可以通过乘以某个“基本型表达式”值将有限的小数范围转换为整数。

I.e.通过执行* 100(0-1599)可以将0.00到15.99的值转换为11位整数,并且(100 * 100)的sqrt为100,所以通过输入* 10000,您将得到值0-2550000(至少需要22位,四舍五入到24b),然后做整数平方根将得到* 100的结果(并适合于11位),所以你可以进一步将它分成两个值除以100.

这个对于人来说可能看起来很简单,但在现实世界中,当使用8/16b寄存器进行小数计算时,通常按照该原则完成,但使用两个幂,即* 256 * 256,这可以通过将值16剩下的位。除以256则将值向右移动8。

因此,对于每个二进制数字的数字方法,您将需要创建24位加/减/移位器代码段。然后输入数字是24位数的最高8位。 (即输入值10 =>(10<<16) == 0x0A0000)=>简单换档。计算那个的sqrt(0x0329或0x032A,取决于你是否设法截断或在最后一位舍入),就是这样,结果肯定会适合12位,上面的4位是整个零件0-15,低8位是“数量1/256”值(0x29/256 = 0.16015625)中的小数。它可以通过简单的移动/和而再次分开,即不需要多个/ div操作。因此,它仍然是很多工作,但它是合理的(在8b CPU上做24位乘法/除法比加/减/移位扩展更痛苦)。并解释为什么您选择了4:8 fixed-point格式的结果,以便从结果的小数部分使用完整的8位精度,并使其对于进一步的二进制计算更简单。 (在8:8的固定点0.5 = 0x0080 ...尝试添加,看看会发生什么:0x0080 + 0x0080 = 0x0100 = 1.0没有任何复杂的篡改结果..这就是我们如何做8位CPU的低精度小数计算例如对于正弦/余弦效应,乘法/除法更简单,也是0。5:0x0080 * 0x0080 =(0x4000 >> 8)= 0x0040 = 0.25)。