NOTE这是一个理论问题。我对实际代码的性能感到满意。我只是好奇是否有替代方案。
有没有一种技巧可以将常量值(本身是 2 的整数幂)除以整数变量值,而无需使用实际的除法运算?
// The fixed value of the numerator
#define SIGNAL_PULSE_COUNT 0x4000UL
// The division that could use a neat trick.
uint32_t signalToReferenceRatio(uint32_t referenceCount)
{
// Promote the numerator to a 64 bit value, shift it left by 32 so
// the result has an adequate number of bits of precision, and divide
// by the numerator.
return (uint32_t)((((uint64_t)SIGNAL_PULSE_COUNT) << 32) / referenceCount);
}
我找到了几个(很多)关于除以常量(整数和浮点数)的技巧的参考资料。例如,问题整数除以 3 最快的方法是什么?有许多很好的答案,包括对其他学术和社区材料的参考。
鉴于分子是常数,并且它是 2 的整数幂,是否有一个巧妙的技巧可以用来代替实际的 64 位除法?某种按位运算(移位、AND、XOR 之类的东西)或类似的?
我不希望任何精度损失(由于整数舍入而超过可能的半位)大于进行实际除法的精度损失,因为仪器的精度取决于此测量的精度。
"Let the compiler decide" is not an answer, because I want to know if there is a trick.
额外的上下文信息
我正在 16 位数据、24 位指令字微控制器上开发驱动程序。驱动器对外围模块进行了一些处理,以获得固定数量的信号频率脉冲的参考频率的脉冲计数。所需的结果是信号脉冲与参考脉冲的比率,以无符号 32 位值表示。该函数的算术由我正在为其开发驱动程序的设备的制造商定义,并且对结果进行进一步处理以获得浮点实际值,但这超出了本问题的范围。
我正在使用的微控制器有一个数字信号处理器,它有许多我可以使用的除法运算,如果有必要,我不害怕这样做。除了将汇编指令放在一起以使其工作之外,这种方法还需要克服一些小挑战,例如 DSP 用于在 BLDC 驱动器 ISR 中执行 PID 功能,但没有什么是我无法管理的。