MATLAB社区

MATLAB,社区和更多

Double Your Pleasure - Fun with Shifty Digits .加倍你的快乐

你今天要享受博客招待了。但首先……

数字1947和7194之间的关系是什么?仔细看,你会发现它们是一样的,除了数字7被从后面移到了前面。

微小的文本更改会对数字空间产生很大影响。MATLAB中央英雄约翰D 'Errico他在下面的客座文章中对这种关系有话要说。但在此之前,我想做一些评论。第一个是感谢约翰寄给我这篇文章!他给我发了一封生活的脚本(后缀为MLX的MATLAB文件类型),我在这里将其转换为一篇WordPress博客文章。这就引出了我的第二个评论:你愿意成为这个网站的客座博主吗?如果你有一个有趣的话题的现场脚本,你想发表它,发送给我(gulley@mathworks.com)。我们可以一起合作,谁知道呢?你可能会在matlabcentral上署名。

现在你请客。看约翰如何用灵巧的击球解决了一个棘手的问题。不过我会要求你们,一旦你们理解了问题的表述,在结束之前,试着自己解决它。我打赌你不会做得像约翰那样好。不管怎样,我不能……

双你的快乐

通过约翰D 'Errico

哪个正整数在其最后一位(即个位)被移动到第一或最高位时加倍?假设这些数字用十进制表示。事实上,这是一个众所周知的问题。例如,你可以找到它讨论了在YouTube上

这个问题在二进制中也很有趣。是否存在二进制解?也就是说,是否存在一个二进制数,比如10101011101,如果我们将这个单位位移到这个数的左端,这个数就会恰好翻倍?

唉,我们可以证明这样的解永远不可能存在,至少在二进制中不可能存在。证明很简单。假设存在一个解,恰好由N个二进制位组成。我们所描述的移位不会增加数字中的比特数。它仅仅是对现有位元的纯粹转换。

然而,当你将任何二进制数乘以2时,会发生什么呢?只要这个数是非零的,那么如果你乘以2,你总是将这个数的比特数增加1。因此我们的目标对于任何二进制数都是不可能的。如果数字是以3或以上为基数写的,这是有可能发生的。我们可以稍后研究这种可能性,但首先,这在基数10中是如何工作的?

回到以10为基数的问题上,我们假设存在一个十进制数,将最低阶的十进制数从单位位置循环移动到现在的最高阶数,然后将数字翻倍。同样,这不会改变数字中的小数位数。

我们可以尝试一些简单的例子,看看它是如何工作的。例如,考虑数字102。这里的变换会让我们创建一个新的数字210,通过将2从最低位移动到最高位来实现。然而,这并没有使数字翻倍。

2 * 102 ~ = 210
ans =逻辑1

我们可以尝试其他数字,比如12345,但是将这个数字翻倍不会得到51234。事实上,我断言用蛮力解决这个问题需要一些努力。我们需要用数学来解决问题。

我们的目标是找到这种形式的小数

在这个表达式中,y是一个单位数整数,x是一个任意顺序的整数。组合起来,它们必须满足以下关系:

在这个关系中,P是数字n中的小数位数仅仅是将个位左移P位。如果存在多个解,我们需要寻找最小的解。万博 尤文图斯

一个重要的问题是,个位是否可以为0?如果y大于0呢?然后控制方程简化为相当简单的情况

解x == 0。所以这个问题的唯一可能的解如果问题中的数字是0,那就是N = 0。因为我们已经要求N必须是正整数,这种情况是不可能的。因此,y必须来自集合[1:9]。通过一些额外的努力,我们可能会更完整,但1:9是一个好的开始。现在回到这个问题的控制方程,分离等式两边的x和y。

如果这个方程中的变量是整数,那么算术基本定理告诉我们19(作为质数)必须除y,或者它必须除y.但是,我们刚刚说过y必须来自集合1:9。我们现在可以得出结论,19必须分开

那么,P的最小次幂是多少,使19能除10^P-2?(注意:下面使用的SYM命令来自符号数学工具箱

P = find(mod(sym(10).^(1:100) - 2,19) == 0)
P = 17 35 53 71 89
差异(P)
Ans = 18 18 18 18

这是有用的。最小的P次方19的整数除数是17。似乎在这一点之后,每18次10的幂都有相同的性质,但我们首先感兴趣的是P=17的情况,就好像存在一个最小的解,它可能有18个小数。我之前确实说过,用蛮力来解决这个问题是很困难的。

至少,如果存在解,我们可以用int64进行计算。双精度将失败我们,因为双精度敲出大约16个十进制数字,在你不能再准确地表示一个整数。然而,headroom在int64中存在,因为

intmax (“int64”
ans =int649223372036854775807

那是一个有19个小数的数字。Uint64将允许我们稍微推高一些,但int64完全足够了。

现在,假设集合中有一个个位数1:9?

unitsdigit = int64(1:9)”;P = int64 (17);

现在我们有足够的信息来解x。

x = (int64(10)^P - 2)*unitsdigit/int64(19);N = 10*x + unitsdigit
N =9×1 int64列向量5263157894736821 105263157894736842 15789473682105263 2105263157894736884 263157894736842105 315789473684210526 368421052631578947 421052631578947368 473684210526315789

这些是x的可能值,我们可以看看它们是否成立。也就是说,如果把N乘以2,就会得到相同的结果,就像把个位的数字转置后变成最高阶的数字一样。

(2 * N, P * 10 ^ unitsdigit + x)
ans =9×2 int64矩阵105263157894736842 105263157894736842 210526315789473684 210526315789473684 315789473684210526 210526315789473684 210526315789473684 105263157894736842 105263157894736842 526315789473684210 631578947368421052 631578947368421052 736842105263157894 736842105263157894 736842105263157894 631578947368421052 631578947368421052 526315789473684210

第一种情况,y == 1,测试失败,因为我们看到第二个最高位插入了一个额外的0。然而,这就只剩下x == 2的第二种情况作为最小解。这必须是最小的具有期望性质的数。

N (2)
ans =int64105263157894736842
2 * (10 * x (2) + unitsdigit (2)) = = 10 ^ P * unitsdigit (2) + x (2)
ans =逻辑1

还发现了8个其他解,除了它们不是最小解万博 尤文图斯外,它们都是有效的。超过这个点,下一个解将有36个小数,远远超过了甚至uint64的限制。

同样,在这一点上要小心,因为这些计算在双精度运算中会失败。

|
  • 打印
  • 发送电子邮件

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。