Ima*_*ist 10 algorithm rational-numbers
是否有算法来计算以下内容?
一些例子:
1/2 = 1/10 = 0.1 // 1 = false, 2 = N/A, 3 = N/A, 4 = N/A
1/3 = 1/11 = 0.010101... // 1 = true, 2 = -2, 3 = 10
2/3 = 10/11 = 0.101010... // 1 = true, 2 = -1, 3 = 10
4/3 = 100/11 = 1.010101... // 1 = true, 2 = 0, 3 = 10
1/5 = 1/101 = 0.001100110011... // 1 = true, 2 = -3, 3 = 1100
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?效率是一个大问题.算法的描述比代码更受欢迎,但我会得到我能得到的答案.
同样值得注意的是,基数不是什么大问题; 我可以将算法转换为二进制(或者如果它在,例如基数为256以便使用chars,我可以使用它).我这样说是因为如果你在解释它可能更容易在基地10解释:).
Ste*_*ham 11
我可以给出一个提示 - 基数十位的重复小数是所有分数,分母至少有一个素数因子而不是两个和五个.如果分母不包含素数因子2或5,则它们总是可以用所有9的分母表示.然后,分子是重复部分,9的数量是重复部分的长度.
3 _
- = 0.3
9
1 142857 ______
- = ------ = 0.142857
7 999999
Run Code Online (Sandbox Code Playgroud)
如果分母中存在两个或五个素因子,则重复部分不在第一个位置开始.
17 17 ______
-- = ----- = 0.4857142
35 5 * 7
Run Code Online (Sandbox Code Playgroud)
但我不记得如何推导非重复部分及其长度.
这似乎很好地转化为基础二.只有具有两个分母幂的分数是非重复的.通过断言分母中只有一个位被设置,可以很容易地检查这一点.
1/2 = 1/10 = 0.1
1/4 = 1/100 = 0.01
3/4 = 11/100 = 0.11
5/8 = 101/1000 = 0.101
Run Code Online (Sandbox Code Playgroud)
具有奇数分母的所有分数应该是重复的,并且可以通过用形式中的分母表示分数来获得模式及其长度2^n-1.
__
1/3 = 1/(2^2-1) = 1/11 = 0.01
__
2/3 = 2/(2^2-1) = 10/11 = 0.10
__
4/3 => 1 + 1/3 => 1.01
__
10/3 => 3 + 1/3 => 11.01
____
1/5 = 3/15 = 3/(2^4-1) = 11/1111 = 0.0011
________
11/17 = 165/255 = 11/(2^8-1) = 10100101/11111111 = 0.10100101
Run Code Online (Sandbox Code Playgroud)
至于十号基础,我不知道如何处理包含但不是两个幂的分母 - 例如12 = 3 * 2^2.
首先,你的一个例子是错误的.的重复部分1/5是0011,而不是1100,它开始于小数部分的最开始.
重复的小数是这样的:
a/b = c + d(2-n + 2-n-k + 2-n-2k + ...)
= c + 2-n * d / (1 - 2-k)
在哪个n和d你想要的.
例如,
1/10(dec) = 1/1010(bin) = 0.0001100110011... // 1 = true, 2 = -1, 3 = 0011
可以用公式表示
a = 1, b = 10(dec), c = 0, d = 0.0011(bin), n = 1, k = 4;
(1 - 2-k) = 0.1111
因此,1/10 = 0.1 * 0.0011/0.1111.重复十进制表示的关键部分是通过除以或它的任意倍数来生成的.所以你可以找到一种方法来表达你的分母(比如建立常数表),或做一个大数除法(这是相对的慢)并找到循环.没有快速的方法来做到这一点.(2n - 1)
要找到重复模式,只需跟踪沿线使用的值即可:
1/5 = 1/101:
1 < 101 => 0
(decimal separator here)
10 < 101 => 0
100 < 101 => 0
1000 >= 101 => 1
1000 - 101 = 11
110 >= 101 => 1
110 - 101 = 1
10 -> match
Run Code Online (Sandbox Code Playgroud)
当您达到与第二位相同的值时,该过程将从该点开始重复,一遍又一遍地产生相同的位模式。模式“0011”从第二位开始重复(小数点分隔符后的第一位)。
如果您希望模式以“1”开头,您可以旋转它,直到它匹配该条件:
"0011" from the second bit
"0110" from the third bit
"1100" from the fourth bit
Run Code Online (Sandbox Code Playgroud)
编辑:
C# 中的示例:
void FindPattern(int n1, int n2) {
int digit = -1;
while (n1 >= n2) {
n2 <<= 1;
digit++;
}
Dictionary<int, int> states = new Dictionary<int, int>();
bool found = false;
while (n1 > 0 || digit >= 0) {
if (digit == -1) Console.Write('.');
n1 <<= 1;
if (states.ContainsKey(n1)) {
Console.WriteLine(digit >= 0 ? new String('0', digit + 1) : String.Empty);
Console.WriteLine("Repeat from digit {0} length {1}.", states[n1], states[n1] - digit);
found = true;
break;
}
states.Add(n1, digit);
if (n1 < n2) {
Console.Write('0');
} else {
Console.Write('1');
n1 -= n2;
}
digit--;
}
if (!found) {
Console.WriteLine();
Console.WriteLine("No repeat.");
}
}
Run Code Online (Sandbox Code Playgroud)
用你的例子调用它输出:
.1
No repeat.
.01
Repeat from digit -1 length 2.
.10
Repeat from digit -1 length 2.
1.0
Repeat from digit 0 length 2.
.0011
Repeat from digit -1 length 4.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13565 次 |
| 最近记录: |