我有一个工作算法来确定分数是否是无限重复以及哪些数字是重复的:
std::vector<integer_type> rd, dg;
integer_type d ( m_numer ), r;
do {
integer_type q, aux;
rd.push_back ( r = ( aux = _remquo<T, GCD, CHKOP> () ( d, m_denom, q ) ) < zero_ ?
integer_type ( -aux ) : aux );
dg.push_back ( q < zero_ ? integer_type ( -q ) : q );
d = op_multiplies() ( base, r );
} while ( ! ( r == zero_ || std::find ( rd.rbegin() + 1, rd.rend(), r ) != rd.rend() ) );
备注:
rd
包含余数dg
包含小数结果数字_remquo
整数除以第一个和第二个操作数,并将余数存储在第三个参数中,忽略模板参数base
可被视为小数值10
m_numer
是分数m_denom
是分数的分母问题:
我想至少摆脱std::find ( rd.rbegin() + 1, rd.rend(), r ) != rd.rend() )
,也就是说我想要检测剩余部分是否已经出现过,并且充其量(为了摆脱rd
向量)之间的距离从右到左的最后一位数到rd
中的第一个重复数字。
问题是,我想在合理的时间内(不花费反向搜索剩余向量的时间)用 HUGE 重复数字序列(如1083448249/12172166
)来分析数字。 / p>
有人有什么想法吗?
答案 0 :(得分:2)
直接计算十进制扩展的数字,不带bignums。使用Floyd的循环检测方法来计算周期。在Python中(循环检测代码由Wikipedia提供):
#!/usr/bin/env python3
def floyd(f, x0):
tortoise = f(x0)
hare = f(f(x0))
while tortoise != hare:
tortoise = f(tortoise)
hare = f(f(hare))
mu = 0
tortoise = x0
while tortoise != hare:
tortoise = f(tortoise)
hare = f(hare)
mu += 1
lam = 1
hare = f(tortoise)
while tortoise != hare:
hare = f(hare)
lam += 1
return (lam, mu)
def repeating_decimal(n, d):
q, r = divmod(n, d)
decimal = [str(q), '.']
period, first_repeat = floyd(lambda r: 10 * r % d, r)
for i in range(first_repeat + period):
q, r = divmod(10 * r, d)
decimal.append(str(q))
return '{}({})'.format(''.join(decimal[:2 + first_repeat]), ''.join(decimal[2 + first_repeat:]))
print(repeating_decimal(1, 75))
print(repeating_decimal(1083448249, 12172166))