落叶 发表于 2016-5-16 09:47:37

如何调用GMP大数库中的开N次方函数mpz_root()

这个函数原型mpz_root(mpz_t rop,mpz_t op,unsigned long int n),它只提供N次根整数部分,这个函数在PDF文件中并没有注明传参的要求(也许是我没查到),即使是正整数不进行一些处理也得不到正确答案,如果要对小数开方,和需要更高的精度,也需要一些前期和后期的处理,因为我曾写过手工开N次方程序,昨天经过调试,发现两个函数前后处理大致一样,方法如下:
例:对1.23456789123456789E12开9次方,精度9
如果是科学计数法表示的数,如:1.23456789123456789E12,转换成 1234567891234.56789
把数以小数点位置向左和向右分别分成N段,这个例子转换成:000001234 567891234 567890000
这个函数有个特点,如果你需要M精度的数,你需要传M*N长的数,如果数没有这么长,后面补零,这个例子你需要传:
000001234 567891234 567890000 000000000 000000000 000000000 000000000 000000000 000000000
函数返回后小数点的位置为:经过前期整理后的数,它的小数点左方的位数,除以N,这里是18\9=2,返回结果为220547258,加小数点后为22.0547258

补充内容 (2016-5-18 14:32):
(小数点位置向左和向右分别分成N段)改为:小数点位置向左和向右分别分成N整数倍的段

补充内容 (2016-5-18 19:37):
用上述方法调用mpz_root()成功,并用于我自已的算式计算器。

wayne 发表于 2016-5-18 09:00:11

用 MPFR的mpfr_root
http://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005froot

落叶 发表于 2016-5-19 15:21:22

本帖最后由 落叶 于 2016-5-19 16:07 编辑

因为这个函数的传参特殊性,当开方次数较高,或要求精度较高时,出现堆栈空间溢出错误,增大堆栈空间也不行(也可能操作不对),目前10000精度可以提供开51次方正确运算,用时7.8秒,实际开方次数还可大一点,
所以当开方次数要求较大时,我用mpz_root()函数计算20位初值(我自已写的初值程序没有优化,特慢),再用我自已写的迭代式计算,10000精度开51次方正确运算,用时4.8秒,竟比GMP的还要快些,然后我减少开方数测试,一直到开25次方时,GMP胜出,mpz_root()10000精度开25次方正确运算,用时2.9秒,注:测试被开方数为999999999
运用两者合作的方式,可以开25500次方,10000精度,被开方数为999999999,用时28.5秒。(为什么用25500开方,因为再大,mpz_root()函数就快停工了,只有减少初值位数,它才能提供更高次的开方)
开25500次方,10000精度,被开方数为111111111,用时8.8秒,这里被开方数是9位,实际参入运算的大都是一万位,即使用一万位被开方数,用时也在这附近,而且规律特乱。最高时用时70多秒

liangbch 发表于 2016-5-19 21:35:26

楼主可否测测MPFR库的log和sin函数的性能。

落叶 发表于 2016-5-20 10:48:25

本帖最后由 落叶 于 2016-5-20 11:18 编辑

因为我用的是VB6.0,VC6.0,是在找到别人编译好的lib库后,并找到介绍GMP的GMP中文.pdf 后,才尝试调用GMP,并且是通过VC写DLL调用,
MPFR库没中文帮助,中间所涉细节更多,我一时难以调用成功,不知道MPFR库在log,sin,mpfr_root的万位用时是多少?
在windows平台调用linux上的函数我头好疼!
因为开平方程序的速度提高ln(9) ,万位运算,20次开平方分解,得数为1.0000020954........用时330ms左右
240次分解得数为1.000....00000xx,中间的零为71个,用时3.84秒.

wayne 发表于 2016-5-20 14:42:02

可以试试用visual studio 2015编译。

liangbch 发表于 2016-6-6 21:47:02

能否举个例子?
页: [1]
查看完整版本: 如何调用GMP大数库中的开N次方函数mpz_root()