2016-08-15 68 views
-1
2> PI = 3.14159265358979323846264338. 
3.141592653589793 
3> PI. 
3.141592653589793 

PI中剩下的数字发生了什么?如何获得完整的价值?为什么当存储在Erlang的变量中时,浮点值会被截断?

+1

[Erlang和大数字]的可能的复制(HTTP:/ /stackoverflow.com/questions/9250915/erlang-and-big-numbers) –

+1

事实是,对于大多数实际问题,Pi的值将比计算中的其他值准确得多 –

回答

7

Erlang使用IEEE 754-1985双精度(64位)浮点数,精度约为十六进制数字。换句话说,你所看到的是预期的。

您当然也可以只使用math:pi/0,即3.1415926535897932

4

@迈克尔给了你一个正确的答案,只是为了好玩,我在这里放了一个小程序,它计算出一个与你想要的pi值相近的整数部分。有多少正确的数字(至少)你想这需要作为参数:K,并返回元组: {Pi*10^K, Num, Div}和PI由Num/Div近似:

8> pi:pi(5). 
{314159,1231847548,392109375} 
9> 1231847548/392109375. 
3.141591674516836 
10> pi:pi(16).   
{31415926535897932,1954593375063141623418966719395892212, 
622166394751939884889125823974609375} 
11> 1954593375063141623418966719395892212/622166394751939884889125823974609375. 
3.141592653589793 
12> pi:pi(100).                 
{31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679, 
76687493427849560932551539133547355657552111418520642454352142367859087475777099790110509028596728165604330274537401085479755361074012954953620747810364589561632946227768531437131849315704805073879011158859557501594908388272923613955511642353579477204804, 
24410387304738988881243138674543333937873180956639377144249334863653319012629901313275720024646578388088082064861007931480541676642001787010751232779539604168044020067382957776693277819044947249055510862819577525863190547994463486247695982456207275390625} 

-module (pi). 

-export ([arctan/2,pi/1,pgcd/2,cf/2,fra/2]). 

%% @doc 
%% arctan({N:integer(),D:integer()},P:integer()) -> {N1:integer(),D1:integer()} 
%% evaluate the value of arctan(N/D) with a precision of P digits 
%% return the result as a fraction N1/D1 
arctan({N,D},P) -> 
    N2=N*N, 
    D2=D*D, 
    arctan([{N,D}],N2,D2,-1,3,N2*N,D2*D,P). 

%% @doc 
%% L is the list of {D,N} terms of the result, 
%% N2 and D2 are the square values of initial N,D 
%% S is the sign of the next term 
%% 1/F is the coefficient of the next term of the serie 
%% Nc/Dc is the next power of the initial N/D number 
%% P the precision 
arctan(L,_N2,_D2,_S,F,Nc,Dc,P) when P*Nc < F*Dc -> 
    sumterm(L); 
arctan(L,N2,D2,S,F,Nc,Dc,P) -> 
    arctan([{S*Nc,F*Dc}|L],N2,D2,-S,F+2,Nc*N2,Dc*D2,P). 

sumterm(L) -> 
    D = lists:foldl(fun({_,X},A) -> X*A end,1,L), 
    N =lists:foldl(fun({X,Y},A) -> X * D div Y + A end,0,L), 
    {N,D}. 

pi(P) -> 
    P1 = list_to_integer(lists:reverse(string:chars($0,P,"1"))), 
    {N1,D1} = arctan({1,5},32*P1), 
    {N2,D2} = arctan({1,239},8*P1), 
    N3 = 16*N1*D2 - 4*N2*D1, 
    D3 = D1*D2, 
    P3 = pgcd(D3,N3), 
    N4 = N3 div P3, 
    D4 = D3 div P3, 
    {(N4*P1) div D4, N4, D4}. 

-spec pgcd(non_neg_integer(),non_neg_integer()) -> non_neg_integer(). 
%% @doc Compute the greatest common divider of A and B 
pgcd(A,B) when is_integer(A), is_integer(B), A >= 0, B >= 0 -> 
    gcd(A,B). 

-spec gcd(non_neg_integer(),non_neg_integer()) -> non_neg_integer(). 
gcd(A, B) when A < B -> gcd(B, A); 
gcd(A, 0) -> A; 
gcd(A, B) -> gcd(B, A rem B). 


cf(P,Q) -> cf(P,Q,[]). 

cf(P,1,L) -> lists:reverse([P|L]); 
cf(P,Q,L) -> 
    P1 = P div Q, 
    Q1 = P rem Q, 
    cf(Q,Q1,[P1|L]). 

fra(L,N) -> 
    N1 = min(length(L),N) -1, 
    L1 = lists:sublist(L,N1), 
    P = lists:nth(N1+1,L), 
    fra(P,1,lists:reverse(L1)). 

fra(N,D,[]) -> {N,D}; 
fra(N,D,[H|T]) -> fra(N*H+D,N,T). 
相关问题