Q格式,加减乘除

        Q格式表示为:Qm.n,表示数据用m比特表示整数部分,n比特表示小数部分,共需要 m+n+1位来表示这个数据,多余的一位用作符合位。假设小数点在 n位的左边(从右向左数),从而确定小数的精度
       例如Q15表示小数部分有15位,一个short 型数据,占2个字节,最高位是符号位,后面 15位是小数位,就假设小数点在第 15位左边,表示的范围是: -1<X<0.9999695  。浮点数据转化为 Q15,将数据乘以2^15;Q15数据转化为浮点数据,将数据除以 2^15

       例如:假设数据存储空间为 2个字节,0.333×2^15=10911=0x2A9F ,0.333的所有运算就可以用0x2A9F 表示,同理10911×2^(-15)=0.332977294921875 ,可以看出浮点数据通过 Q格式转化后是有误差的。


       例如:两个小数相乘,

0.333*0.414 = 0.137862 ,0.137862 * 2^15 = 4516 = 0x11A4
0.333*2^15 = 10911 = 0x2A9F 
0.414*2^15 = 13565 = 0x34FD 

short a = 0x2A9F; 
short b = 0x34FD; 
short c = a * b >> 15; //  两个Q15格式的数据相乘后为 Q30格式数据,因此为了得到 Q15的数据结果需要右移15位
       c的结果是0x11A4=0001000110100100 ,这个数据同样是 Q15格式的,它的小数点假设在第15位左边,即为0.001000110100100=0.1378173828125... 和实际结0.137862 差距不大。或者0x11A4 / 2^15 = 0.1378173828125 


Q格式的运算
1> 定点加减法:须转换成相同的 Q格式才能加减
2> 定点乘法:   不同Q格式的数据相乘,相当于Q值相加,即Q15数据乘以Q10数据后的结果是 Q25格式的数据
3> 定点除法:不同 Q格式的数据相除,相当于 Q值相减
4> 定点左移:左移相当于 Q值增加
5> 定点右移:右移相当于 Q减少


Q格式的应用格式
       实际应用中,浮点运算大都时候都是既有整数部分,也有小数部分的。所以要选择一个适当的定标格式才能更好的处理运算。一般用如下两种方法:
1> 使用时使用适中的定标,既可以表示一定的整数复位也可以表示小数复位,如对于 2812的32位系统,使用Q15格式,可表示-65536.0~65535.999969482 区间内的数据。
2> 全部采用小数,这样因为小数之间相乘永远是小数,永远不会溢出。取一个极限最大值(最好使用2的n次幂),转换成x/Max 的小数(如果Max是取的2的n次幂,就可以使用移位代替除法) 。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
大整数的加减乘除是常见的数学运算,可以通过编程实现。下面是Python语言实现大整数加减乘除的示例代码: 1. 大整数加法: ```python def add(num1, num2): # 将两个字符串逆序后转换为列表 list1 = list(num1[::-1]) list2 = list(num2[::-1]) res = [] # 存储结果的列表 carry = 0 # 进位 while list1 or list2 or carry: # 如果列表中还有元素或者有进位 n1 = int(list1.pop()) if list1 else 0 n2 = int(list2.pop()) if list2 else 0 # 相加并加上进位 carry, s = divmod(n1 + n2 + carry, 10) res.append(str(s)) # 将结果列表逆序转换为字符串 return ''.join(res[::-1]) ``` 2. 大整数减法: ```python def sub(num1, num2): # 将两个字符串逆序后转换为列表 list1 = list(num1[::-1]) list2 = list(num2[::-1]) res = [] # 存储结果的列表 borrow = 0 # 借位 while list1: # 如果列表中还有元素 n1 = int(list1.pop()) n2 = int(list2.pop()) if list2 else 0 # 减去借位并相减 n1 -= borrow borrow = 0 if n1 < n2: n1 += 10 borrow = 1 res.append(str(n1 - n2)) # 去掉结果前面的0 while res and res[-1] == '0': res.pop() # 如果结果为空,则表示两个数相等,返回0 return ''.join(res[::-1]) if res else '0' ``` 3. 大整数乘法: ```python def mul(num1, num2): # 将两个字符串逆序后转换为列表 list1 = list(num1[::-1]) list2 = list(num2[::-1]) res = [0] * (len(list1) + len(list2)) # 存储结果的列表 for i in range(len(list1)): for j in range(len(list2)): # 计算乘积并加上当前位置的进位 res[i+j] += int(list1[i]) * int(list2[j]) # 处理进位 res[i+j+1] += res[i+j] // 10 res[i+j] %= 10 # 去掉结果前面的0 while res and res[-1] == 0: res.pop() # 将结果列表转换为字符串 return ''.join(map(str, res[::-1])) ``` 4. 大整数除法: ```python def div(num1, num2): # 将两个字符串转换为整数 n1 = int(num1) n2 = int(num2) # 计算商和余数 q, r = divmod(n1, n2) # 将结果转换为字符串并返回 return str(q), str(r) ``` 需要注意的是,上述代码中只考虑了正整数的情况,对于负整数的处理需要额外考虑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值