只是为了完整性(或无用的表示),以下是如何使用整数完成任务,无需乘法,通过线性搜索(应该在大多数情况下为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)。
256字节长度如何查找包含结果的表格? (呃,更像是512B长,因为小数部分......是定点数学8:8?我猜)(如果你只有256B的小数部分,整个部分可以简单地+缓慢地完成一个循环) – Ped7g
不幸的是,这是和分配,我必须计算它,否则这将是一个可行的选择,但感谢您的意见。 –
虽然我会这样做作为最后的手段,如果我不明白。 (你建议制作一个程序,将插入的数字与256个结果进行比较,如果发现它是正确的,则结束) –