二郎神; math.pow,为什么不是默认的整数或浮点数/整数的类型?

时间:2016-03-03 16:53:44

标签: erlang

我认为Erlang处理任意精度整数。但看起来math.pow默认使用浮点数:

使用linux实用程序bc

88^99
31899548991064687385194313314353745484864573065650712770111884048604\
75359372836550565046276541670202826515718633320519821593616663471686\
151960018780508843851702573924250277584030257178740785152

删除反斜杠:

3189954899106468738519431331435374548486457306565071277011188404860475359372836550565046276541670202826515718633320519821593616663471686151960018780508843851702573924250277584030257178740785152

在Erlang中:

float_to_list(math:pow(88,99),[{scientific,192}]).
"3.189954899106468677983468001676918389478607432406058411199358053788184470654582587122118156926366989707830958889227847846886750593566290713618113587727930256898153980172821794148406939795587072e+192"

并排:

bc:  3189954899106468738519431331435374548486457306565071277011188404860475359372836550565046276541670202826515718633320519821593616663471686151960018780508843851702573924250277584030257178740785152
erl: 3189954899106468677983468001676918389478607432406058411199358053788184470654582587122118156926366989707830958889227847846886750593566290713618113587727930256898153980172821794148406939795587072

我写了一个天真的函数:

integerpow(N, 1) -> N;
integerpow(N, M) -> N*integerpow(N, M-1).

产生正确的答案。

但是当两个参数都是整数时,似乎默认行为应该产生正确的答案,为什么不是

2 个答案:

答案 0 :(得分:4)

因为math模块只包含了C库中的内容。正如the manual page所说:

  

的错误

     

因为这些是C库,所以错误是相同的。

(尽管你可能会质疑返回一个浮点数而不是一个bignum是一个“bug”)

这也是pow的类型签名所说的:

pow(X, Y) -> float()

    Y = X = number()

也就是说,函数被指定为接受任何数字,即整数和浮点数,但总是返回一个浮点数。

那为什么呢?

我找不到任何关于是否可以接受向标准库添加bignum取幂函数的贡献的权威答案,因此请尝试并提交拉取请求! (或许an EEP。)

虽然我确实在erlang-questions邮件列表上找到了an alternative implementation(返回与base参数相同类型的值),但在类似主题上找到了a Stack Overflow question,并且{{3}讨论如何使用非常大的数字,甚至比bignums还要大。

答案 1 :(得分:0)

Erlang,就此而言,任何库,甚至是简单的计算器,都不能通过多次天赋相乘来计算大整数幂。他们使用一种名为Exponentiation_by_squaring的特定数学公式。它通过多项式近似计算功率。对于较小的数字,近似值是精确的,但对于较大的数字,它的准确度越来越低,当然这取决于底层库中实现的精度。 math library in Erlangunderlying C implementation的类似NIF的代理。

修改

这似乎是duplicate of this question

math.stackexchange.com上还有一个问题引用computation algorithm的相同来源。

所以,你已经在问题本身回答了你的问题。 Erlang处理任意精度整数,但模块math没有,它默认使用float