当前位置: 首页 > 后端技术 > PHP

GMP扩展学习在PHP中操作任意精度

时间:2023-03-29 13:51:10 PHP

各种开发语言,整数都有最大位数,超过位数就无法显示和操作。其实这也是精度越界后精度损失的问题。在我们的PHP代码中,最大的整数非常大,我们可以用PHP_INT_MAX看到它。但是,当整数超过一定位数时,就会用科学计数法显示,这不是我们想要的结果。别担心,GMP扩展旨在处理这种情况。GMP扩展与PHP源码包一起发布。在安装扩展之前,需要在系统环境中安装gmp-devel。在CentOS上直接运行yuninstallgmp-devel即可。非常大的数的精度损失问题我们先来看看直接打印非常大的数会发生什么。echoPHP_INT_MAX;//92233720368547758071.2312312312312E+26$a=123123123123123123123123123;echo$a,PHP_EOL;//1.2312312312312E+26echo$a+1,PHP_EOL;//1.2312312312312E+26可以看到,显示的结果都是科学计算的合法形式。而对于简单的算术运算,基本没有区别。就像我们最后给$a+1的情况一样,和原来的数据显示结果是一样的。$b=gmp_init("123123123123123123123123123");echo$b,PHP_EOL;//123123123123123123123123123echogmp_add($b,1),PHP_EOL;//123123123123123123123123124当我们使用GMP扩展后,就可以使用gmp_init()来实例化这样的超大数。打印的结果仍然是标准的数字格式。不过,这里需要注意的是,这个扩展实际上是将我们要操作的超大数转换成了字符串表示。gmp_add()是GMP的加法运算函数。这很简单。就是加两个参数,返回一个GMP对象。var_dump($b);//object(GMP)#1(1){//["num"]=>//string(27)"123123123123123123123123123"//}echo$b+1,PHP_EOL;//123123123123123123123123124这可以通过打印gmp_init()返回的$b对象看出。它的内容实际上是一个字符串。同时这个对象也重写了\_\_toString()方法,所以我们可以直接echo它。另外,GMP对象也会重载运算符,所以直接对GMP对象进行日常的运算符操作是没有问题的。简单的算术运算除了重载运算符之外,GMP扩展还提供了一系列算术运算函数,就像我们在上面看到的gmp_add()一样。echogmp_sub($b,1),PHP_EOL;//123123123123123123123123122echogmp_mul($b,2),PHP_EOL;//246246246246246246246246246echogmp_div("123123123123123123123123123",3),PHP_EOL;//41041041041041041041041041echogmp_mod($b,5),PHP_EOL;//3这四个是减法、乘法、除法、余数的计算。很简单,这里就不多说了。这里需要注意的一点是,它们接收的参数可以是int类型,也可以是string类型。就像gmp_init()接收到的参数一样。echogmp_abs("-123123123123123123123123123"),PHP_EOL;//123123123123123123123123123echogmp_pow($b,3),PHP_EOL;//186646078483862213537835104788626518464464518626789005835538??2138624840786461867echogmp_sqrt($b),PHP_EOL;//11096085937082这三个函数分别是取绝对值、乘方,二次根的计算函数。它类似于普通的数学计算函数。位操作GMP扩展还可以轻松地执行数据的位操作和二进制操作。例如位运算中的AND、OR、XOR。echogmp_and($b,"2222222222"),PHP_EOL;//2151965570echogmp_or($b,"2222222222"),PHP_EOL;//123123123123123123193379775echogmp_xor($b,"3333333333"),PHP_EOL;//123123123123123120012088038还可以将一个数字转换为二进制格式导出。echogmp_export($b),PHP_EOL;//e?U?(c?O?当然二进制也有相应的函数导入,这里就不演示了,大家可以自行在文档中找到相应的函数测试了解。$pop1=gmp_init("10000101",2);//3echogmp_popcount($pop1),PHP_EOL;$pop2=gmp_init("11111110",2);//7echogmp_popcount($pop2),PHP_EOL;gmp_popcount()函数是用于获取二进制表示的字符中1的个数,例如本次测试代码返回的结果。$s1=gmp_init("10111",2);echogmp_scan0($s1,0),PHP_EOL;//3$s2=gmp_init("101110000",2);echogmp_scan0($s2,0),PHP_EOL;//0$s1=gmp_init("10111",2);echogmp_scan1($s1,0),PHP_EOL;//0$s2=gmp_init("101110000",2);echogmp_scan1($s2,0),PHP_EOL;//4gmp_scan0()和gmp_scan1()函数分别是找到0或1第一次出现的位置。它的第二个参数是指示从哪里开始查找。另外,他们的搜索方向是从右到左,从下标0的位置开始。//83490559526159213//12500000000echogmp_random_bits(99999),PHP_EOL;//289814632948807684404778811091812938699609………………就和普通的生成随机数的函数,除了GMP扩展库下的这两个函数可以生成更大范围的数字,返回GMP对象的格式。对于gmp_random_bits(),最大范围是12500000000,如果我的机器使用这个随机因子,会直接报超出内存。而使用99999这个随机因子生成的随机数已经很大了,大家可以自己试试。阶乘这是普通数学库中不存在的函数。直接帮我们计算阶乘的结果,不用自己写算法。echogmp_fact(5),PHP_EOL;//1205*4*3*2*1=120echogmp_fact(50),PHP_EOL;//3041409320171337804361260816660647688443776415689605120000000000000乘以480...*49,GMP还提供了一个非常高大上的直接获取和判断素数的功能。一般来说,质数(primenumbers)也是面试中很常见的算法题。我们在面试的时候还是要掌握自己的手写能力,但是手写之后我们可以告诉面试官,GMP里面有现成的功能。会带来一些奖励积分。echogmp_nextprime(10),PHP_EOL;//11echogmp_nextprime(1000),PHP_EOL;//1009echogmp_prob_prime(6),PHP_EOL;//0echogmp_prob_prime("11111111111111111"),OLme;//2gmp_nextprime()是获取指定数后的下一个素数。gmp_prob_prime()是判断写入的数是不是素数。它有三个结果,0表示不是质数,1表示可能(疑似)质数,2表示肯定是质数。数据签名信息echogmp_sign("500"),PHP_EOL;//1echogmp_sign("-500"),PHP_EOL;//-1echogmp_sign("0"),PHP_EOL;//0最后一个gmp_sign()函数使用来表示给定数据的符号信息,即正数和负数。同样是三个结果,1代表正数,-1代表负数,0代表0。为什么这里有一个特殊的0呢?因为0既不是正数也不是负数,它本身就是一种特殊的存在。综上所述,扩大GMP的方式还有很多,就不一一列举了。这里我们只选取一些常用的内容来给大家介绍一下。虽然是文档,但是不能直接从文档中复制出来,所以还是要自己去文档里面查看更多的内容。我们学习的主要目的是知道有这么个东西,以免在真正的业务需求中偶然发现相关信息。当内容被蒙蔽时。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/8。GMP扩展学习在PHP中操作任意精度大小。PHP参考文档:https://www.php.net/manual/zh/book.gmp.php============各媒体平台均可搜索【硬核项目经理】

最新推荐
猜你喜欢