我在Atmega328上玩直接数字合成波表。
给定8位小数值F和两个8位值A,B,计算A和B之间的线性插值的最有效方法是什么?我可以想到两种方法:
备选方案1:
插值= ((A << 8) + (B - A) * F) >> 8
(仅当B&gt; = A时才会起作用,但我可以将其包装在if / else中,如果A&gt; B则交换A和B)
备选方案2:
插值= A + (B - A) * (F / 256)
我选择哪一个或者编译器是否会以相同的方式优化它们是否有效?
是否有更好的方法不涉及乘法或除法?
编辑:将alternative 2
中的分母从255
更改为256
答案 0 :(得分:0)
假设
F
每个计数为1/256(并且不能完全表达1)A
,B
和F
为uint8_t
线性插值可以是
uint8_t I = A + (uint8_t)(((int16_t)(B-A) * F) >> 8)
如果您希望255
表达1.0
,那么您必须除以255而不是移位,但我想我会以不同的方式处理one case
。例如,对F
使用16位并检查高字节,然后使用上面的公式与低位字节(如果小于1)。
以上几行与您的备选行几乎完全相同,但由于A
和B
为8位,因此插值结果不能超过8位范围,因此可以使用uint8_t完成添加。 / p>
由于第二个被乘数(A
)始终为零,因此您的备选方案2始终会获得F/256
。