2

在 8 位微控制器上,我想执行以下操作:

16bit_integer = another_16bit_integer * 0.997;

尽可能少的指令。

4

9 回答 9

4

32位整数算术怎么样?

16bit_integer = (int16_t) (another_16bit_integer * (int32_t) 997 / 1000);

32 位足以存储 (INT16_MAX × 997),对大 1000 倍的值求和,然后再除回到 16 位刻度。

于 2008-08-26T04:31:27.657 回答
3

位移通常非常快:

y = 0xFF3B * (int32_t) x >> 16;

这可能最好写成:

y = (0.997 * 0x10000) * (int32_t)x >> 16;

一个好的编译器会产生等效的输出。

如果您的整数是有符号的,则常量应更改为 0x8000 和 15。

于 2008-09-03T11:45:05.303 回答
2

您可能打算在那里进行一些舍入,而不是将结果截断为整数,否则操作的目的实际上是有限的。

但是,由于您使用该特定公式提出了问题,因此您想起了您的结果集确实很粗糙。对于前 333 个数字,结果为:another_16bit_integer-1。你可以用类似的东西来近似它(甚至可能是完全正确的,当我没有在脑海中执行时):

16bit_integer = another_16bit_integer - 1 - (another_16bit_integer/334);

编辑:无符号整数,你自己处理 0 。

于 2008-08-26T13:24:14.273 回答
1

在我的平台上(Atmel AVR 8 位微控制器,运行 gcc)

16bit_integer = another_16bit_integer * 0.997;

大约需要 26 条指令。

16bit_integer = (int16_t) (another_16bit_integer * (int32_t) 997 / 1000);

大约需要 25 条指令。

于 2008-08-26T04:38:28.840 回答
1

这是执行此操作的一种非常快速的方法:

a = b * 0.99609375;

它与您想要的相似,但速度快得多。

a  = b;
a -= b>>8;

或者使用仅适用于小端系统(如 PIC)的技巧甚至更快。

a  = b;
a -= *((int8*)((&b)+1));

在我的脑海中,这归结为 PIC18 上的以下汇编程序:

; a = b
MOVFF 0xc4, 0xc2
NOP
MOVFF 0xc5, 0xc3
NOP

; a -= *((int8*)((&b)+1));
MOVF  0xc5, w
SUBWF 0xc2, f
BTFSC STATUS, C
DECF  0xc
于 2011-01-21T12:06:46.313 回答
0

预计算查找表:

16bit_integer = products[another_16bit_integer];
于 2008-08-26T05:34:52.467 回答
0

预计算查找表:

16bit_integer = products[another_16bit_integer];

这在 AVR 上不会那么好用,16 位地址空间将被耗尽。

于 2008-08-26T06:19:14.153 回答
0

由于您使用的是 8 位处理器,因此您可能只能处理 16 位结果,而不是 32 位结果。为了减少 16 位溢出问题,我将重述如下公式:

result16 = operand16 - (operand16 * 3)/1000

这将为高达 21845 的无符号整数或高达 10922 的有符号整数提供准确的结果。我假设处理器可以进行 16 位整数除法。如果你不能,那么你需要以艰难的方式进行除法。如果不存在乘法指令或乘法仅适用于 8 位操作数,则乘以 3 可以通过简单的移位和加法来完成。

如果不知道确切的微处理器,就不可能确定这样的计算需要多长时间。

于 2008-08-26T06:23:33.067 回答
0

在我的平台上(Atmel AVR 8 位微控制器,运行 gcc)

16bit_integer = another_16bit_integer * 0.997;

大约需要 26 条指令。

16bit_integer = (int16_t) (another_16bit_integer * (int32_t) 997 / 1000);

大约需要 25 条指令。

Atmel AVR是 RISC 芯片,因此计数指令是有效的比较。

于 2008-08-26T06:28:05.833 回答