dingsir的个人博客分享 http://blog.sciencenet.cn/u/dingsir

博文

老贴再贴: 求任意自然数的任意自然数次方的结果个位数

已有 3197 次阅读 2020-3-14 17:58 |个人分类:其它兴趣|系统分类:论文交流| 自然数, 乘方, 个位数

这个是2009年本人一个老贴,淘出来再看看,稍作精简.

有一次我问老爸:2100次方的结果,其个位数是几?当时我也不知道是几,但想想应该有些规律,研究了一下,发现应该是六,这个不是硬乘出来的,而且推断的结果.我用手机上的Python环境计算了一下2**100,结果一长串,个位的确是六。于是,我再进一步思考,是否可以求解任意一个自然数的任意自然数次方的结果,其个位数是否可以心算出来?经过努力,发现都是有规律的。

  最近在学习VC++,于是想把这点思考的结果固化下来,代码如下,在DOS下运行。写了两个函数,第一个函数让我理清了思路,第二个函数非常简洁但不容易理解,实质上就是对第一个函数的浓缩。

-----------C++源代码--开始-------------------------------

# include <iostream.h>
/*
求取结果的原理:个位数的幂决定了结果的幂。对某个数而言,特定倍数的结果总是一样的尾数,如34n次幂总是1结尾,因此可以容易算出4n+1次方的尾数为1*34n+2次方的尾数 1*3*394n+3 次方的尾数为 1*3*3*3=27,即为7.因此可以知道任意次方的结果的尾数。
 
因此,对底数以10取模,对幂则根据不同的数字来决定。   
 di
底数  mi
 digewei
:底的个位数,它决定了结果的个位数
 miyu:
幂的余数,取模之后。

逐步分析即可以得到结果,如方法1所示。也可以将结果总结成一个数组,即方法2所使用的结果。

*/

int GetLastDigit_1(int di, int mi)
{
 int digewei;
 int miyu;

 digewei=di % 10;
 switch (digewei)
{
  case 0: return 0; break;
  case 1: return 1; break;
  case 5: return 5; break;
  case 6: return 6; break;


  case 2: 
   miyu=mi%4;
   switch (miyu)
   {
   case 0: return 6;break; // 2^4n=6
   case 1: return 2;break; //2^4n+1=6*2=12, so 2
   case 2: return 4;break; //2^4n+2=6*2*2=24, so 4
   case 3: return 8;break; //2^4n+3=6*2*2*2=48, so 8;
   };
   break;
  case 3:
   miyu=mi%4;
   switch (miyu)
   {
   case 0: return 1;break; //3^4n=1
   case 1: return 3;break; //3^4n+1=1*3=3, so 3
   case 2: return 9;break; //3^4n+2=1*3*3=9, so 9
   case 3: return 7;break; //3^4n+3=1*3*3*3=27, so 27
   };
   break;
  case 4:
   miyu=mi%2;
   switch(miyu)
   {
   case 0: return 6;break; //4^2n=6
   case 1: return 4;break; //4^2n+1=6*4=4;
   };
   break;
  case 7:
   miyu=mi%4;
   switch (miyu)
   {
   case 0: return 1;break; //7^4n=49*49=1
   case 1: return 7;break; //7^4n+1=1*7=7;
   case 2: return 9;break; //7^4n+2=1*7*7=49, so 9
   case 3: return 3;break; //7^4n+3=1*7*7*7=49*7=3
   };
   break;
  case 8:
   miyu=mi%4;
   switch (miyu)
   {
   case 0: return 6;break; //8^4n=64*64=16;
   case 1: return 8;break; //8^4n+1=6*8=48, so 8
   case 2: return 4;break; //8^4n+2=6*8*8, so 4
   case 3: return 2;break; //8^4n+3=6*8*8*8, so 2
   }
   break;
  case 9:
   miyu=mi%2;
   switch (miyu)
   {
   case 0: return 1;break; //9^2n=81^n, so 1
   case 1: return 9;break; //9^2n+1=1*9=9;
   };
   break;
 };

};

int GetLastDigit_2(int di, int mi)
{/*
根据方法1的结果,将其整理成数组来直接处理更为节省代码。
数据的第一维对应底的个位数,从09
数组的第二维四个数字,依次为(底的个位)^(%4)结果的个位。
*/
int myarr[10][4]={
  {0, 0, 0, 0},
  {1, 1, 1, 1},
  {6, 2, 4, 8},
  {1, 3, 9, 7},
  {6, 4, 6, 4},
  {5, 5, 5, 5},
  {6, 6, 6, 6},
  {1, 7, 9, 3},
  {6, 8, 4, 2},
  {1, 9, 1, 9},
  };

return (myarr[di%10][mi%4]);
};

int main()
{
 int di;  int mi;
 cout<<"Please input the ground: " ;
 cin>>di;
 cout<<"\n Please input the power: ";
 cin>>mi;

 cout<<"the Last digit is " << GetLastDigit_1(di, mi) <<endl;
 cout<<"the Last digit is " << GetLastDigit_2(di, mi) <<endl;
 return 0;
}

-----------------源代码结束------------

我很奇怪的是,为什么所有的数字如果它的指数是4nn为自然数),无论n是多少其尾数都是同样的?

我的数学水平太差,不能证明。

因为只为自然数的4n次方结果的个位数为0,1,5,6才有可能保持(无论n是多少,乘幂的结果个位数不变)。那么10个数字(09)的4n次方,为什么个位数都落在这个范围内呢?

另外,我发现,第二个函数的数组中,第二列正好是09,这绝对不是巧合的。

或者,这个问题可以转化为:

假设m, n均为自然数,%为取余计算符,证明以下命题(不使用穷举法):

blob.png 

2009.7.5增加以下内容:

由于python里大数的计算自有支持,故添加一点:因此如果底与幂不同时超过1000,就打印出来。

print("本程序计算任选一个正整数的任意正整数次方的结果的尾数。\n")

EndList=[[0000], [1111], [6248],  [1397],  [6464],[5,555],  [6666],  [1793],  [6842],  [1919]]
g=int(input(
'请输入底数(正整数):\n'))
p=int(input(
'请输入指数(正整数):\n'))
print(g, 
"", p, "次方,结果的个位数是 ",EndList[g %10][p %4])
if ((p>1000or (g>1000)):
    exit
else:
    print (
"完整结果如下:\n", g**p)

-------------------

我把这个问题发到了CSDN.net上,有一位网友提供了一个解法,但是我看不懂。

提供者: deng2000

试着给个证明,不知道算不算避免了穷举.先证明几个引理
引理
若整数a, b, c, d满足 
a%10 = c%10 
b%10 = d%10, 
(a+b)%10 = (c+d)%10 
  (a*b)%10 = (c*d)%10 
证明: a=10*A+m, c=10*C+m, b=10*B+n,d=10*D+n, 代人上式即得
  
引理
a%10 = b%10, 则对任意整数n, 
  (a^n)%10 = (b^n)%10, 
特别地, 
  (a^n)%10 = ((a%10)^n)%10 
证明:重复运用引理1的乘法部分即得 
  
引理
a10互素,则存在整数k,使得 
  (a*k)%10 = 1 
证明: 因为a10互素,Eulid辗转相除法知,存在整数k,n使得 
    a*k + 10*n = 1 
因此 (a*k)%10 = (1-10*n)%10 = 1%10 - (10*n)%10 = 1 

引理
对任意整数n, 
  (2^(4n+1))%10 = 2 
  (5^(4n+1))%10 = 5 
证明: 2^(4n+1)-2 = 2*(2^4n-1) = 2*(16^n-1) 
                = 2*(16-1)*(16^(n-1) + 16^(n-2) + ... + 16 + 1) 
                = 30 * (16^(n-1) + 16^(n-2) + ... + 16 + 1) 
   
能被10整除 
   
(2^(4n+1))%10 = (2^(4n+1)-2+2)%10 = ((2^(4n+1)-2)%10 + 2)%10 = 2 
   
同理可证 (5^(4n+1))%10 = 5 
  
引理
若整数a10互素,则对任意整数n, 
  (a^4n)%10 = 1 
证明:我们知道,任意与10互素的数除以10的余数只有4种情况: 1, 3, 7, 9 
考虑如下4个数
  a*1, a*3, a*7, a*9 
因为a10互素,这4个数也分别与10互素. 考虑这4个数除以10的余数,显然每个余数都只能在集合{1,3,7,9}中取值.我们还断言这4个余数是彼此不等的.如若不然
  (a*m)%10 = (a*n)%10  其中m,n是集合{1,3,7,9}中的两个不同的数
运用引理3, 存在整数k使得 (a*k)%10=1, 在上式两边同乘以k,
    (k*a*m)%10 = (k*a*n)%10 
因此, ((k*a)%10 * m)%10 = ((k*a)%10 * n)%10 
  m%10 = n%10, 这与假设矛盾
既然这4个余数彼此不等,又只能在集合{1,3,7,9}中取值,则这4个余数就是1,3,7,9按某一顺序的排列,因此
  ((a*1) * (a*3) * (a*7) * (a*9))%10 = (1*3*7*9)%10 
亦即 (a^4 * (1*3*7*9))%10 = (1*3*7*9)%10 
再运用引理3,存在整数p使得 (1*3*7*9*p)%10 = 1, 在上式两边同乘以p,即得 
  (a^4)%10 = 1 
因此 (a^4n)%10 = ((a^4)^n)%10 = (1^n)%10 = 1 
(
顺便提一句, 引理5是初等数论中Euler定理的一个特例

有了以上的引理,我们再来证明本命题: 对任意整数m,n, 
  (m^4n)%10 = (m^(4*(n+1))%10      ----- (1) 
  (m^(4n+1))%10 = m%10            ----- (2) 
证明: m=2^a*5^b*k, 其中a,b为整数,k是与10互素的整数 
(m^(4n+1))%10 = ((2^a*5^b*k)^(4n+1))%10 
= ((2^(4n+1))^a * (5^(4n+1))^b * k^(4n+1)) % 10 
= (2^a * 5^b * k^4n * k) % 10 
= (2^a * 5^b  * k) % 10 
= m%10 
此即(2) 

下面证明(1) 
左边=(m^4n)%10=(m^(4(n-1)+4))%10 = (m^(4(n-1)+1+3))%10 = (m^(4(n-1)+1)*m^3)%10 = (m*m^3)%10 = (m^4)%10 
右边=m^(4*(n+1))%10 = (m^(4n+1) * m^3)%10 = (m*m^3)%10 = (m^4)%10 
(1)式也成立 

欢迎数学达人讨论讨论



https://blog.sciencenet.cn/blog-1213210-1223503.html

上一篇:CAS数字的校验
下一篇:MOA、密位 及其快速换算
收藏 IP: 112.17.247.*| 热度|

1 刘山亮

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-11-25 12:53

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部