为什么浮点值存储在Erlang的变量中时会被截断?

为什么浮点值存储在Erlang的变量中时会被截断?,erlang,Erlang,PI中其余的数字怎么了?如何获得完整值?Erlang使用IEEE 754-1985双精度(64位)浮点,其精度约为16位十进制数字。换句话说,你所看到的是预期的 当然,你也可以使用math:pi/0,也就是3.1415926535897932@Michael给了你一个正确的答案,只是为了好玩,我在这里放了一个小程序,可以计算一个整数分数,这个分数与pi的值非常接近。它以您想要的正确位数(至少)为参数:K,并返回元组: {Pi*10^K,Num,Div}和Pi近似为Num/Div: 2> P

PI中其余的数字怎么了?如何获得完整值?

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


当然,你也可以使用
math:pi/0
,也就是
3.1415926535897932

@Michael给了你一个正确的答案,只是为了好玩,我在这里放了一个小程序,可以计算一个整数分数,这个分数与pi的值非常接近。它以您想要的正确位数(至少)为参数:K,并返回元组:
{Pi*10^K,Num,Div}
和Pi近似为
Num/Div

2> PI = 3.14159265358979323846264338.
3.141592653589793
3> PI.
3.141592653589793
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}
-模块(pi)。
-出口([arctan/2、pi/1、pgcd/2、cf/2、fra/2])。
%%@doc
%%arctan({N:integer(),D:integer()},P:integer())->{N1:integer(),D1:integer()}
%%以P位精度评估arctan(N/D)值
%%将结果作为分数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是结果的{D,N}项的列表,
%%N2和D2是初始N,D的平方值
%%S是下学期的标志
%%1/F是级数下一项的系数
%%Nc/Dc是初始N/D编号的下一次幂
%%P精度
当P*Nc
萨姆特姆(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=列表:foldl(fun({uux},A)->X*A end,1,L),
N=列表:foldl(fun({X,Y},A)->X*D div Y+A end,0,L),
{N,D}。
pi(P)->
P1=列表到整数(列表:反向(字符串:字符($0,P,“1”)),
{N1,D1}=arctan({1,5},32*P1),
{N2,D2}=arctan({1239},8*P1),
N3=16*N1*D2-4*N2*D1,
D3=D1*D2,
P3=pgcd(D3,N3),
N4=N3分区P3,
D4=D3分区P3,
{(N4*P1)div D4,N4,D4}。
-规范pgcd(非负整数(),非负整数())->非负整数()。
%%@doc计算A和B的最大公除法
pgcd(A,B)当是整数(A),是整数(B),A>=0,B>=0->
gcd(A,B)。
-规范gcd(非负整数(),非负整数())->非负整数()。
当Agcd(B,A)时,gcd(A,B);
gcd(A,0)->A;
gcd(A,B)->gcd(B,A,B)。
cf(P,Q)->cf(P,Q,[])。
cf(P,1,L)->列表:反向([P | L]);
cf(P,Q,L)->
P1=P div Q,
Q1=P rem Q,
cf(Q,Q1,[P1 | L])。
fra(左,北)->
N1=最小值(长度(L),N)-1,
L1=列表:子列表(L,N1),
P=列表:n(N1+1,L),
fra(P,1,列表:反向(L1))。
fra(N,D,[])->{N,D};
fra(N,D,[H | T])->fra(N*H+D,N,T)。

事实的可能重复是,对于大多数实际问题,Pi的值将比计算中的其他值精确得多
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).