定点数的定标

转自:http://blog.csdn.net/longxuekun1992/article/details/52895302

1. 选取合适的定标值(加载操作数)
定标的大小,影响着整数部分和小数部分的位数,定标的过程其实是在操作数动态范围和精度之间做权衡的过程。

设一个变量可能出现的最大绝对值为|max|,n为正整数,满足2^(n-1) < |max| < 2^n,则定标Q按如下规则选取最合适:

Q = 有效数据位 – n


对于32位的有符号数,数据有效位=31。如|max| = 2.75,选Q = 31 – 2 =29是最合适的。

2. 定点数之间的运算
两个定点数进行运算,它们的定标可能相同也可能不同,那该遵循怎样的规则来进行加减乘除等基本运算呢?

网上有些资料通过分别举加、减、乘、除实际运算的例子来说明这一问题,虽然很详细,但还是不够直观。

来看一看,平时我们用十进制做两个数的加减和乘除是怎么弄的。

加减法:先对位,后加减;
乘除法:先乘除,后取小数点。

而定点数之间的加减乘除,撇开符号位不谈,其过程是一样一样的:

加减法:先对标,后加减;
乘除法:先乘除,后定标。

3. 结果重新定标(返回结果)
两个定点数运算完成之后,所得结果的定标、动态范围、精度要求等都可能发生了变化,因此可能需要进行重新定标。

比如Q15*Q15 -> Q30,但我们依然希望得到一个Q15的数怎么办?其实只需做一个简单的右移15位操作就好,其它情况同理。

大家可以仔细体会下这里的意思,然后再找具体的例子对照感受下,看是不是觉得简单多了呢。

http://blog.csdn.net/times_poem/article/details/51505014

Q12的正数的最大值是 0 111 . 111111111111,第一个0是符号位,后面的数都是1,那么这个数是十进制的多少呢,很好运算,就是 0x7fff / 2^12 = 7.999755859375。对于Qn格式的定点小数的表达的数值就它的整数值除以2^n。在计算机中还是以整数来运算,我们把它想象成实际所表达的值的时候,进行这个运算。

反过来把一个实际所要表达的值x转换Qn型的定点小数的时候,就是x*2^n了。例如 0.2的Q12型定点小数为:0.2*2^12 = 819.2,由于这个数要用整数储存, 所以是819 即 0x0333。因为舍弃了小数部分,所以0x0333不是精确的0.2,实际上它是819/2^12 =0.199951171875。

我们用数学表达式做一下总结:
x表示实际的数(*一个浮点数), q表示它的Qn型定点小数(一个整数)。
q = (int) (x * 2^n)
x = (float)q/2^n

用Q12来计算2.1 * 2.2,先把2.1 2.2转换为Q12定点小数:
2.1 * 2^12 = 8601.6 = 8602
2.2 * 2^12 = 9011.2 = 9011
(8602 * 9011) >> 12 = 18923
18923的实际值是18923/2^12 = 4.619873046875 和实际的结果 4.62相差0.000126953125,对于一般的计算已经足够精确了。

http://www.eeworld.com.cn/DSP/2014/1025/article_4006.html

q = quantizer('fixed', 'ceil', 'saturate', [32 30]);

  FixedNum=bin2dec(num2bin(q,1.999999999));

 

 

http://blog.163.com/xiada_action/blog/static/7423460220100255911247/

1.q = quantizer('fixed', 'ceil', 'saturate', [8 6]);imgbits=num2bin(q,k);这是将一个小数k,比如0.256 变成二进制。小数点后面3位用6位二进制表示。

现再将编出来的二进制 恢复成10进制 小数:
二进制小数转换没有现成的函数,要自己编的。         或者你利用二进制整数的转换函数bin2dec()         比如二进制的0.1101         那你就先把小数部分转换成十进制整数        >> d=bin2dec('1101')                   d =                         13              然后再根据位数,小数点后面4位,就除以2^4        >> d/2^4                 ans =                          0.8125
2.写文件:
fid=fopen('sin.coe','wt')
fprintf(fid, '%d',a)
fclose(fid)
读取文件:
(1)fid1=fopen('fx.txt','r');                     %得到文件号
[f,count]=fscanf(fid,'%f %f',[12,90])
%把文件号1的数据读到f中。其中f是[12 90]的矩阵
%这里'%f %f'表示读取数据的形势,他是按原始数据型读出
fclose(fid);%关闭文件
(2) load data.txt
data
(3) a=importdata('data.txt')
posted @ 2017-09-03 20:34  喵喵小学僧  阅读(1421)  评论(0编辑  收藏  举报