2016-10-03 144 views
0

我在blackfin533上发现了一段代码,它的fract32从-1,1开始,格式为1.31。计算两个定点分数的平方根的解释

我不明白为什么需要预换档来计算复数(re,img)的幅度。我知道如果你想用1.31分数格式乘1.31,那么你需要右移31位。

GO_coil_D [0] .RE和GO_coil_D [0] .IM两种fract32

我不能得到什么,下面的代码是这样做的:

norm[0] = norm_fr1x32(GO_coil_D[0].re); 
norm[1] = norm_fr1x32(GO_coil_D[0].im); 
shift = (norm[0] < norm[1]) ? (norm[0] - 1) : (norm[1] - 1); 
vectorFundamentalStored.im = shl_fr1x32(GO_coil_D[0].im,shift);  
vectorFundamentalStored.re = shl_fr1x32(GO_coil_D[0].re,shift); 
vectorFundamentalStored.im = mult_fr1x32x32(vectorFundamentalStored.im, vectorFundamentalStored.im); 
vectorFundamentalStored.re = mult_fr1x32x32(vectorFundamentalStored.re, vectorFundamentalStored.re); 
amplitudeFundamentalStored = sqrt_fr16(round_fr1x32(add_fr1x32(vectorFundamentalStored.re,vectorFundamentalStored.im))) << 16; 
amplitudeFundamentalStored = shr_fr1x32(amplitudeFundamentalStored,shift); 

round_ fr1x32`(fract32 F1)fract16大红大紫的32位FRACT到16位FRACT使用偏舍入。

norm_fr1x32 norm_fr1x32(fract32)int返回标准化输入变量所需的左移位数,以便它位于间隔0x40000000至0x7fffffff中,或位于间隔0x80000000至0xc0000000之间。换句话说,fract32 x; shl_fr1x32(X,norm_fr1x32(X));返回值的范围0x40000000之后为0x7FFFFFFF,或在范围为0x80000000至0xc00000000的

回答

1

1)如果小数部分的最显著Ñ位全部为值“0”比特,并且它们后面是“1 'bit,那么n表现为像值为的浮点二进制指数n,并且其余的31位-n位表现得像尾数。对数字进行平方可将前导'0'位的数量加倍为2 * n并将尾数的大小减小到31-2 * n位。这可能会导致平方运算结果的精度下降。

2)round_fr1x32将1.31分数转换为1.15分数,最多丢失16位的精度。

希望你能看到第1步和第2步可以消除很多数字的精度。对数字进行预缩放会尽可能减少前导“0”位的数量,从而导致在步骤1中丢失的精度降低。事实上,对于两个数字中的一个被平方和相加,导致的数量'0'位n将为零,因此对该数字进行平方后,在将其添加到另一个数字之前,仍然会保留高达31位的精度。 (步骤2会将该精度降低到15位)。

最后,您错误地将两个1.31分数格式数相乘的结果 - 结果需要右移31位而非62位。

样例:

让我们说,真正的部分是一千零二十四分之三和虚部是十进制一千○二十四分之四,所以绝对值应该一千零二十四分之五毕达哥拉斯。

没有预缩放,二进制分数是re = 0.0000000011 2,im = 0.0000000100 2。将它们平方后给出re 2 = 0.00000000000000001001 2,im 2 = 0.00000000000000010000 2。添加正方形给出abs²=0.00000000000000011001₂。舍入到15个小数位得出abs²=0.000000000000001₂。取平方根得出abs =0.000000010110101₂。这与确切的结果0不同。0000000101 2 0.000000000010101 2。当预分级时,两个分数左移6位,给出sre = 0.0011 2,sim = 0.0100 2(我用前缀's'表示'scaled')。将它们平方给出sre 2 = 0.00001001 2,sim 2 = 0.00010000 2。加上正方形给出sabs²=0.00011001₂。舍入到15个小数位不会更改该值。取平方根得出sabs = 0.01010000 2。将其转换为1.31格式并右移6位,得出abs = 0.0000000101 2,这是完全正确的(5/1024十进制)。

+1

我加了一个工作的例子,有和没有预先标定的情况下,实际部分是3/1024(十进制)和虚部为4/1024。希望你能看到绝对值(振幅)应该是5/1024,因为它形成了一个3-4-5的三角形。 –

+0

你能告诉我什么是真实与自身,虚拟与自身相乘的原始问题,然后加上结果,然后取平方根,然后右移31位?这种方法会有什么问题? –

+1

如果你可以很容易地计算1.31格式分数的平方根,那么这样做没有太大问题,但是当实部和虚部平方时,可能会有一些精度位的损失。 –