有没有办法在不进行实际除法运算的情况下除以13?
我发现只有能检查13分度的测试。
我正在寻找类似于该除以10的东西:
static A_UINT32 div_10(A_UINT32 duration)
{
A_UINT64 invDivisor = 0x1999999A;
return (A_UINT32)((invDivisor * duration) >> 32);
}
或除以3:
static A_UINT32 div_3(A_UINT32 duration)
{
duration += (duration + 0x2) >> 2;
duration += (duration + 0x8) >> 4;
duration += (duration + 0x80) >> 8;
duration += (duration + 0x8000) >> 16;
return duration >>= 2;
}
答案 0 :(得分:1)
您正在寻找两个正整数k和m,s.t.
[n*k/2^m] = [n/13], 0 <= n < 2^32
其中[x]
表示“舍入”有理数x
和n
贯穿所有32位无符号整数。这些2 ^ 32方程可简化为两个不等式:
k > 2^m/13
k < 2^m*N/(13N-1)
其中N = [2^32/13]
。因此,我们必须寻找一个m
s.t. 2^m/13
和2^m*N/(13N-1)
之间有一个整数值。由于我们使用64位进行计算,因此必须确保对于所有感兴趣的n,n*k
都可以用64位表示,因此我们需要(2^32-1)*k < 2^64
,即k < 2^32
。从第一个不等式中,我们得到2^m/13 < 2^32-1
,这意味着m <= 35
。现在计算k
的{{1}}的上下边界,直到35。我们得到下表:
m
当 m 2^m/13 2^m*N/(13N-1)
....
31 165191049.85 165191049.88
32 330382099.69 330382099.77
33 660764199.38 660764199.54
34 1321528398.77 1321528399.08
35 2643056797.54 2643056798.15
时,k范围内没有整数值。但是对于m < 34
和m=34
,范围内只有一个整数。因此,可能的解决方案是:m=35
或k = 1321528399, m = 34
。
以下是其他除数的解决方案:
k = 2643056798, m = 35
如果要用64位计算来计算所有32位无符号整数的正确结果,似乎没有这种形式的除以7、14、19、21(及更多)的解决方案。