PHP中的任意精度数学

18

我目前正在尝试了解如何在PHP中使用任意精度数字。因此,我的第一个问题是什么是任意精度数学。我尝试谷歌搜索一个好的定义,但由于某种原因没有人能用足够简单的话语表达清楚。

其次,在PHP中BCMath和GMP库之间有何区别?我听说GMP的API更“新”,但我不确定。哪个更好呢?

最后,我的问题是BCMath/GMP接受什么类型的数字。显然它接受以字符串形式表示的普通整数(例如“5.34”),但是我看到过直接使用八位字符串表示常规整数(例如“\x12\x23\x45\x67”)的BCMath函数实现,这被称为“bigint”,但是谷歌对我没有什么帮助。


理论上,两者都允许使用任意长度的数字,只要它们作为字符串输入到库中即可。这归结于哪个库对您的目的具有更好的API。bc纯粹使用字符串,而gmp可以接受字符串,但也使用自己的内部表示。 - Marc B
注意:要使用任意精度算术,您可以使用类似 brick/math 的库,该库根据每个扩展程序的可用性自动使用 GMP、BCMath 或纯 PHP。这样,您就不必选择 GMP 或 BCMath,并且可以使用一个漂亮的面向对象的 API。 - BenMorel
2个回答

27

什么是任意精度数学?
任意精度算术(也称为“大数运算”)引入了一种在数字位数仅受可用内存限制的情况下执行算术运算的方式。这与主机系统的CPU / ALU提供的定点精度算术不同,其中表示的数字的最大大小/精度是这些硬件处理器寄存器位数的因素。

定点精度算术快速、高效且内置/普遍可用。 然而,它仅适用于有限的(即使有时“足够大”的)数值范围。 任意精度算术较慢,对存储器有些浪费并需要专用库,例如GMP或BCMath。

BCMath和GMP库之间有何区别?
最显著的区别是GMP适用于[任意精度]整数值,而BCMath允许[任意精度] 小数 / 浮点数值。
两个API都不难学习,但BCMath可能更加直观(除了支持类似于浮点数的值)

通常选择特定库而不是另一个库通常是由预期用途(或在给定平台上的可用性)驱动的。 在进行MP应用之前,大多数库都可以胜任并且在其类别内通常是相当等效的(当然,如果需要浮点数,则避免仅限于整数的库)。

BCMath / GMP接受哪些类型的数字?
与大多数任意精度数学软件包一样,这两个库使用字符串作为其API,即表示其输入和输出数字值。
内部上... 一些软件包如GMP具有其自己的数字表示形式。 这些结构的特定内容通常是在最小化存储要求以及允许快速计算之间进行权衡(包括将此类结构“串行化/反串行化”到/从文本文件中的计算)。
问题中的示例"\x12\x23\x45\x67"被称为BCD,即二进制编码十进制。它允许每个字节存储2个十进制数字,并且有时被任意精度算术库使用。


谢谢你的回答!我只有两件事要澄清。使用BCD而不是常规整数是否有原因?BCMath和GMP是否都接受BCD以及常规整数[对于BCMath来说,也包括浮点数]? - parent5446
BCMath和GMP都不接受以BCD表示的值。与只有一个数字或特殊字符(如点或减号等)的字符串相比,BCD的优点在于更紧凑:每个字节存储2个数字而不是1个数字,同时仍然可以轻松映射到数字的表示(数字中的特定数字对应于恰好一个nibble)。 BCD的一个缺点是它不能用C字符串表示(因为可能出现2个零,这会与空终止符混淆)。 - mjv
通常情况下,您不需要使用BCD,但是这种格式有时是任意精度算术库的内部格式,并且也用于特殊应用程序。 - mjv
2
这真的是一次很有启发性的经历。这意味着在涉及货币计算时,BCMath扩展是最好的选择。即使Blockchain的PHP API客户端库也建议使用BCMath进行比特币计算!注意:永远不要忘记指定您的精度(通常是第三个参数)! - Ema4rl

6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接