演算法求循環節
❶ 4.954954……的循環節是多少用簡便方法記作多少
如果無限小數的小數點後,從某一位起向右進行到某一位止的一節數字循環出現,首尾銜接,稱這種小數為循環小數,這一節數字稱為循環節。 把循環小數寫成個別項與一個無窮等比數列的和的形式後可以化成一個分數
對一個大整數求倒數,用牛頓法可以快速達到很高的精度,但需要的空間很大。如果求一個10^300數量級的質數p的倒數,其循環節長度有可能達到p-1,沒有一台計算機的內存能夠儲存整個循環節的數據。如果用普通的除法,只需儲存余數,佔用的內存不大,可卻可能要計算p-1次,不可能算完。則只要有循環節的長度就可以,不用輸出循環節的內容,這種方法解決了這個問題。
另外,這個問題的另一種描述是:給定大整數n(可能是質數也可能是合數,且不知道這個數的分解形式),求最小的k使10^k ≡1 (mod n),對a^k ≡1 (mod n),若n與a互素,求分母n的歐拉函數值ψ(n).那麼循環節長度k必是ψ(n)的約數;若n與a有公因子,顯然無解。根據這個性質,對每個約數試驗就可以了。
ψ(n)的求法:
設n=p1^c1*p2^c2*...*pk^ck(pi為素數),
那麼ψ(n)=(p1-1)*p1^(c1-1)*(p2-1)*p2^(c2-1)*...*(pk-1)*pk^(ck-1)。
因此求ψ(n)與將n因數分解密切相關,如果n有300位的話,對300位數分解是困難的。當然,以上只是對a^k ≡1 (mod n)(a為與n互素的任意數)形式來討論的。如果a=2,可能有更好的辦法。
事實上提出這個問題的初衷,是發現大數分解問題可以轉化為求一個大數的倒數的循環節的長度
給定n,在RSA加密中,n肯定是兩個質數的積。設n=p*q,此時1/n的循環節的長度l|gcd(p-1,q-1)。
❷ a/7的循環節怎麼求
1/7=0.142857
2/7=0.285714
3/7=0.428571
4/7=0.571428
5/7=0.714285
6/7=0.857154
循環部分數字都為142857
27*n/6=2000
n=12.35
27*12*6=1944
2000-1944=56
56-27*2=2
循環小數尾數為2
符合條件為6/7
a=6
n=16*(6+2)+1=130
設第一車間X,第二車間y
60x+70y=8440
x-y=28
x=80
y=52
❸ 用c語言怎麼求循環小數的循環節
1、判斷循環的關鍵是在確定每位小數的時候,判斷余數是否出現與之前的相同。
2、常式:
intrepetend(//求循環節的函數,返回值為循環長度,共3個參數
inta,//第一個參數為被除數
intb,//第二個參數為除數
char*Str)//第三個參數為用於存循環節每一位的數組指針
{intRem[255],//用於存余數的整型數組
Div1=a,//把被除數保存下來,因為後面可能會改變被除數的值
Div2=b;//把除數也保存下來,因為後面可能會改變除數的值
if(a==0orb==0)return0;//如果被除數或者除數為0,函數返回0值
if(Div1<0)Div1=Div1*-1;//正負並不影響求循環節,所以被除數和除數都取絕對值
if(Div2<0)Div2=Div2*-1;//正負並不影響求循環節,所以被除數和除數都取絕對值
for(;Div1*10<Div2;){Div1=Div1*10;}
/*如果被除數乘以10小於除數,就通過一個循環不斷讓被除數乘以10,直到被除數乘以10大於
或者等於被除數,這樣可以清除掉小數點後面的0.000000這些多餘的數據。*/
Rem[0]=Div1%Div2;//第一次保存余數
for(inti=0;;i++)//用一個死循環檢索小數點後面的每一位
{Div1=Rem[i]*10;//每一次的被除數都為前一次余數乘以10
Str[i]=Div1/Div2;//得到第i位小數(0為第1位,1為第2位,以此類推)
Rem[i+1]=Div1%Div2;//保存余數
if(Rem[i+1]==0)//不管小數點後第幾位,如果余數為0,說明能除盡,不會出現循環
{Str[0]=0;//循環節為0
return1;}//函數返回1,這是根據你題目中要求的,但我覺得應該設為0比較合理
for(intj=0;j<=i;j++)//再用一重循環比較之前所有的余數,確定循環節起始點
if(Rem[i+1]==Rem[j])
/*判斷是否出現循環的關鍵是判斷余數是否和之前的某一次相同。如果當前余數等於之前的某一
次余數,說明開始出現循環。循環點的起點為j,終點為i,循環長度為(i-j)+1位小數,當上述判斷為真時,就可以結束函數*/
{for(intk=0;k<=(i-j);k++)Str[k]=Str[j+k];//整理循環節數組
return(i-j)+1;}//函數返回循環長度
}
}
❹ 有沒有求真分數化循環小數循環節的簡單方法比如:求1/133化成小數後循環節長度是幾其中有幾個6
有,對於分母末位數字是1,3,7,9的整數,分數值都是純循環小數。而且通過分子分母同乘一個數,可化成分母末位數字是9,然後分母加1,再除以10,用得數M除分子可從前面向後得到循環節各位數字;用M逐位乘分子各位數字向前加,從後向前得到循環節各位數字。比如1/133=3/399,M=40,向後算是:3除以40得0餘3,記住得數寫後余數寫前寫下30,以此方法繼續為: 30300207 75351318387279396369 99192324 48 81 12120 3於是1/133=0.007518796992481203計18位循環節,下面我們從後向前計算:末位數字是3,3*40加到前面得1203,0*40不要加,2*40加上變成81203,1*40加上得481203,8*40加得32481203,如此等等直到循環.這是我中學時給出的方法,後來發現與印度佛教演算法巧合。M還可用來判別整除性,這里不便詳述,將來可看明年出版的《數學試驗與發現》一書。叢汲泉
❺ 求能找出一個循環小數循環節的C語言編程,即使最後一段循環節不完整
這個問題實際上就是這樣一個問題:
設s是一個字元串,令s^2=ss , s^3=sss , s^n=ssss...s(n個s)。
現在給定一個字元串S,求最短的字元串a,使得a^n=S。
只不過你這個問題還有一個條件,就是最後一個循環節可以不完整。
這個問題,最簡單的演算法就是枚舉所有的可能:
比如2332332332332
先看2是不是,如果不行再看23,不行再看233,233發現可以。
如果233不行,就看2332,。。。。。以此類推。
求給個採納吧。
❻ 如何求無限循環小數的循環節長度
所有循環小數的分數表示都是
循環節/[1-10^(循環節長度)]
如此代入計算吧
❼ c語言問題,如何求兩數相除的循環節
/*判斷循環的關鍵是在確定每位小數的時候,判斷余數是否出現與之前的相同。以下是實現的程序,直接寫完,思路應該是正確的,但還沒有經過驗證,不清楚可以加我QQ:20428920*/
int repetend( //求循環節的函數,返回值為循環長度,共3個參數
int a, //第一個參數為被除數
int b, //第二個參數為除數
char *Str) //第三個參數為用於存循環節每一位的數組指針
{int Rem[255], //用於存余數的整型數組
Div1=a, //把被除數保存下來,因為後面可能會改變被除數的值
Div2=b; //把除數也保存下來,因為後面可能會改變除數的值
if(a==0 or b==0) return 0; //如果被除數或者除數為0,函數返回0值
if(Div1<0) Div1=Div1*-1; //正負並不影響求循環節,所以被除數和除數都取絕對值
if(Div2<0) Div2=Div2*-1; //正負並不影響求循環節,所以被除數和除數都取絕對值
for(;Div1*10<Div2;){Div1=Div1*10;}
/*如果被除數乘以10小於除數,就通過一個循環不斷讓被除數乘以10,直到被除數乘以10大於
或者等於被除數,這樣可以清除掉小數點後面的0.000000這些多餘的數據。*/
Rem[0]=Div1%Div2; //第一次保存余數
for(int i=0;;i++) //用一個死循環檢索小數點後面的每一位
{Div1=Rem[i]*10; //每一次的被除數都為前一次余數乘以10
Str[i]=Div1/Div2; //得到第i位小數(0為第1位,1為第2位,以此類推)
Rem[i+1]=Div1%Div2; //保存余數
if(Rem[i+1]==0) //不管小數點後第幾位,如果余數為0,說明能除盡,不會出現循環
{Str[0]=0; //循環節為0
return 1;} //函數返回1,這是根據你題目中要求的,但我覺得應該設為0比較合理
for(int j=0;j<=i;j++) //再用一重循環比較之前所有的余數,確定循環節起始點
if(Rem[i+1]==Rem[j])
/*判斷是否出現循環的關鍵是判斷余數是否和之前的某一次相同。如果當前余數等於之前的某一
次余數,說明開始出現循環。循環點的起點為j,終點為i,循環長度為(i-j)+1位小數,當上述判斷為真時,就可以結束函數*/
{for(int k=0;k<=(i-j);k++) Str[k]=Str[j+k]; //整理循環節數組
return (i-j)+1;} //函數返回循環長度
}
}
❽ 如何求一個分數化成小數後的循環節求演算法,或者C++/C程序。
#include <stdio.h>
#include <memory.h>
int main(void)
{
int a, b, t;
int used[10000];//b < 10000
memset(used, 0, sizeof(used));
printf("輸入分子,分母:");
scanf("%d%d", &a, &b);
a %= b;//求可以得到小數的部分
//能循環就是出現余數重復出現,則只需找到第一次重復出現的余數
//0是結束標志,先將a置為重復出現,然後每次a = a*10%b求出新得的余數,並檢查該余數是否出現過,有則開始重復,無則置為1,繼續
for(used[0] = 1, used[a] = 1, a = a*10%b; used[a] != 1 ; used[a] = 1, a = a*10%b)
{
;
}
if(a == 0)
{
printf("有限小數\n");
}
else
{
t = a;
printf("循環小數,循環節:");
do
{
printf("%d", a*10/b);
a = a*10%b;
} while (a != t);
printf("\n");
}
return 0;
}
❾ java求循環節
import java.util.*;
public class Xunhuanjie
{
public static void main(String[] args)
{
int[] d=new int[100];//存放除數
int[] r=new int[100];//存放余數
int m,n,i,j,k;
i=0;
System.out.println("請輸入兩個數:");
Scanner in=new Scanner(System.in);
m=in.nextInt();
n=in.nextInt();
d[i]=m/n;
r[i]=m%n;
while(true)
{
i++;
d[i]=r[i-1]*10/n;
r[i]=r[i-1]*10%n;
j=0;
while(r[j]!=r[i])
j++;
if(j<i)
break;
}
System.out.print(m+"/"+n+"="+d[0]+".");
for(k=1;k<=j;k++)
System.out.print(d[k]);
System.out.print("[");
for(k=j+1;k<=i;k++)
System.out.print(d[k]);
System.out.print("]\n");
}
}
這個程序是不嚴謹的,可惜我泛型數組列表學得不好,見諒
比方說7/15,假如一個小學生會怎麼算呢?
1)先商0餘7,這0就是整數部分了
2)然後補0,就是用余的7*10/15,得4餘10
3)然後補0,10*10/15得6,又餘10
第三步得的余數就跟前面第二步一樣了吧.
這就不用繼續算了,循環體肯定是6
大意就是每做一次運算,檢測一下這次運算的余數是不是跟之前某次運算的余數相同,如果有,那麼從之前那次運算到此次運算得到的商都是循環體(這是因為每步都用一樣的演算法,決定每步的商的也就只有上一步運算的余數而已)
我表達能力有限,你能明白嗎?