如何用查表替代运算

对于sin,cos,tan等三角函数来说,使用cpu/fpu计算所花费的时间比加减法员算要慢很多的时间

这就使得在很多密集的三角运算花费了大量的时间,如何在保证一定精度的情况下,使用近似的方法来获取这些函数的数值呢

常规的做法,就是牺牲空间换取时间的查表法

需要注意的是,查表法不是万能的,必须针对特定的函数特殊处理,拿sin(x)作为例子来说

把x从0到90度,每0.01一个单位,把每个点的sin数值计算出来,存储到一个长度9000的表当中去

那么这个时候的精度是0.01吗?

不是

精度说的是,sin(x)的实际数值和查表获得的数值之间的差,要控制精度,就要按照精度来划分值域空间而不是定义域空间,sin(x)在0-90的定义域内值域是0到1,按照0.01划分,只需要100个数值就是了

建立一个长度100的表,把0到1之间的值域分割点的asin数值写入其中(显然表内数据不是等间距的)

具体的计算x的时候,检查这个表,找到x位于哪两个下标所对应的范围内,从而根据下标×0.01获得对应的sin数值。

但是这个查表显然和第一种方式的查表的速度无法相比

如果,对于给定的精度,我们能够确定一个最小的间隔,以这个间隔来划分定义域的话就好了

其实这个问题很好解决,我们可以通过计算导数来判断sin函数,在什么地方数值变化最大,也就是导数数值最大,显然sin的导数是cos,在0的时候最大

因此假定精度是0.01,我们只要计算asin(x)=0.01,x=0.057,为了方便我们取0.05作为间隔,把0到90度的定义域均分成为180份就可以了

对比一下,可以发现,如果直接按照0.01的精度划分定义域,需要9000表长

如果按照精度0.01划分值域,需要表厂100,但是查表的时间不容忽视

按照上述方法,需要180表长,效率一样。

一个特殊函数的查表法:

对于lnx函数,我们知道是可以用 log2(x)/ln(2)的方式来计算

x = 1.m ×2^N

log2对于pc计算机来说,可以通浮点数的内存结构直接提取出来log2的整数部分N,

对于尾数部分,我们建立一个1.0到2.0之间的尾数表,通过浮点数在pc当中的内存结构获取到x的小数部分m,然后直接把他转化成为整数作为表的索引数值就可以了。这样的表的精度一点都不损失。

还可以根据实际的精度要求,只选择m的高几位来降低表的长度。

Modbus协议是一种应用层协议,广泛应用于工业控制领域,它规定了数据帧的结构以及设备之间的通信规则。Modbus协议中的校验码用于确保数据的完整性和正确性。查表法是一种校验码计算的方法,通过预先计算好的校验码来简化校验码的计算过程。 在Modbus协议中,常用的校验码计算方法有两种:循环冗余校验(CRC)和累加和(LRC)。其中,CRC校验比LRC校验更为精确,因此使用更加广泛。CRC校验通常使用16位或32位的多项式,而查表法则是将CRC校验的计算过程通过预计算的方法简化。 查表法的核心思想是预先计算出所有可能字节值的CRC校验结果,并将这些结果存储在一个中。当需要计算一个数据包的CRC值时,可以直接查找这个而不是进行复杂的计算。这个通常是一个256行×16位的数组,每一行代一个可能的字节值的CRC初始值。 具体步骤如下: 1. 初始化CRC寄存器为一个特定的值(例如0xFFFF)。 2. 对数据包中的每个字节重复以下步骤: a. 将CRC寄存器与当前字节进行按位异或(XOR)运算。 b. 查表法:根据异或运算的结果查表得到一个16位的值,并用这个值替换CRC寄存器的值。 c. 对得到的新值进行左移,如果移出的最高位是1,则将寄存器与一个固定的16位多项式进行异或运算。 3. 重复步骤2直到处理完数据包中的所有字节。 4. 最终CRC寄存器中的值即为整个数据包的校验码。 查表法的优点是计算速度快,因为复杂的运算查找的操作替代了。缺点是需要额外的内存空间来存储校验码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值