rootn (float_t x, int_t n)是一个计算第n个根x 1/n的函数,并且受一些编程语言(如 OpenCL)的支持.当使用IEEE-754浮点数时n,假设只x需要处理归一化的操作数,则可以基于对基础位模式的简单操作生成任何有效的低精度起始近似值.
二进制指数root (x, n)将是二进制指数的1/n x.IEEE-754浮点数的指数字段是有偏差的.我们可以简单地将偏置指数除以n,然后应用偏移量来补偿先前忽略的偏差,而不是对指数进行不偏置,将其除去,并重新偏置结果.此外,我们可以简单地划分整个操作数x,重新解释为整数,而不是提取,然后除去指数字段.找到所需的偏移是微不足道的,因为1的参数将返回1的结果n.
如果我们有两个辅助函数可供我们使用,__int_as_float()它将IEEE-754重新解释binary32为int32,并且__float_as_int()重新解释int32操作数为binary32,则我们以rootn (x, n)直接的方式得出以下低精度近似:
rootn (x, n) ~= __int_as_float((int)(__float_as_int(1.0f)*(1.0-1.0/n)) + __float_as_int(x)/n)
Run Code Online (Sandbox Code Playgroud)
通过恒定除数的整数除法的公知优化,__float_as_int (x) / n可以将整数除法简化为移位或乘法加移位.一些有用的例子是:
rootn (x, 2) ~= __int_as_float (0x1fc00000 + __float_as_int (x) / 2) // sqrt (x)
rootn (x, 3) ~= __int_as_float (0x2a555556 + …Run Code Online (Sandbox Code Playgroud) 如何计算整数除法2 64 / n?假设:
unsigned long 是64位如果这样做18446744073709551616ul / n,我们将warning: integer constant is too large for its type在编译时到达。这是因为我们无法在64位CPU中表示2 64。另一种方法如下:
#define IS_POWER_OF_TWO(x) ((x & (x - 1)) == 0)
unsigned long q = 18446744073709551615ul / n;
if (IS_POWER_OF_TWO(n))
return q + 1;
else
return q;
Run Code Online (Sandbox Code Playgroud)
是否有更快的(CPU周期)或更干净的(编码)实现?
注意这是一个理论问题.我很满意我的实际代码的性能.我只是想知道是否有其他选择.
是否有一个技巧可以通过整数变量值对一个常量值进行整数除法,该整数除法本身就是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);
}
Run Code Online (Sandbox Code Playgroud)
我找到了几个(很多)参考,用于通过常量,整数和浮点进行除法的技巧.例如,问题什么是将整数除以3的最快方法?有很多好的答案,包括参考其他学术和社区材料.
鉴于分子是常数,并且它是2的整数幂,是否有一个巧妙的技巧可以用来代替实际的64位除法; 某种逐位操作(移位,AND,XOR,那种东西)或类似的操作?
由于仪器的精度取决于此测量的精度,因此我不希望任何精度损失(超出可能由于整数舍入导致的半位)大于实际除法的精度.
"让编译器决定"不是答案,因为我想知道是否有诀窍.
我正在开发一个16位数据,24位指令字微控制器的驱动程序.驱动器对外围模块做了一些魔术,以获得信号频率的固定数量脉冲的参考频率的脉冲计数.所需结果是信号脉冲与参考脉冲的比率,表示为无符号32位值.该函数的算法由我正在为其开发驱动程序的设备的制造商定义,并且结果被进一步处理以获得浮点实际值,但这超出了该问题的范围.
我正在使用的微控制器有一个数字信号处理器,它有许多我可以使用的除法操作,如果有必要,我不害怕这样做.会有这种方法克服,超越放在一起汇编指令,使其工作,如DSP被用来做一个BLDC驱动ISR一个PID功能一些小的挑战,但没有什么我不能管理.