Предполагая, что вы интерполируете последовательность значений, где предыдущая конечная точка является новой начальной точкой:
(B-A)/(x/255)+A
звучит как плохая идея. Если вы используете базу 255 в качестве представления с фиксированной точкой, вы получите один и тот же интерполант дважды. Вы получаете B, когда x = 255, и B как новый A, когда x = 0.
Использовать 256 в качестве системы с фиксированной точкой. Деления становятся сдвигами, но вам нужна 16-битная арифметика и умножение 8x8 с 16-битным результатом. Предыдущая проблема может быть исправлена простым игнорированием любых битов в старших байтах, когда x mod 256
становится 0. Это предложение использует 16-битное умножение, но не может переполниться. и вы не интерполируете по одному и тому же x дважды.
interp = (a*(256 - x) + b*x) >> 8
256 - x
становится просто вычитанием с заимствованием, поскольку вы получаете 0 - x
.
В PIC отсутствуют следующие операции в наборе команд:
- Сдвиг вправо и влево. (как логическое, так и арифметическое)
- Любая форма умножения.
Вы можете получить сдвиг вправо, используя вместо этого вращение-вправо, а затем замаскировав дополнительные биты слева с помощью побитового и. Прямой способ умножения 8x8 с 16-битным результатом:
void mul16(
unsigned char* hi, /* in: operand1, out: the most significant byte */
unsigned char* lo /* in: operand2, out: the least significant byte */
)
{
unsigned char a,b;
/* loop over the smallest value */
a = (*hi <= *lo) ? *hi : *lo;
b = (*hi <= *lo) ? *lo : *hi;
*hi = *lo = 0;
while(a){
*lo+=b;
if(*lo < b) /* unsigned overflow. Use the carry flag instead.*/
*hi++;
--a;
}
}