我正在使用GNU Multiple Precision(GMP)库对任意精度整数执行一些计算。然后我需要结果的十进制数字。但不是全部:只是,比方说,一百个最重要的数字(即数字开头的数字)或数字中间的选定数字范围(例如1000的数字100..200) -digit number)。
有没有办法在GMP中做到这一点?
我在文档中找不到任何函数来提取一系列十进制数字作为字符串。将mpz_t
转换为字符串的转换函数始终转换整个数字。一个人只能指定基数,而不能指定开始/结束数字。
除了将整个数字转换成一个巨大的字符串而只是拿掉一小部分然后扔掉其余部分之外,还有更好的方法吗?
编辑我需要的不是控制我的数字的精确度或将其限制为特定的固定数字位数,而是从任意数字的数字字符串中选择数字的子集精度。
这是我需要的一个例子:
7^1316831 = 19821203202357042996...2076482743
实际号码有1112852位数,我将其缩小为...
现在,我只需要任意选择这个庞大的数字串的子串。例如,十个最重要的数字(在这种情况下为1982120320
)。或者从1112841到1112849的数字(在这种情况下为21203202
)。或者只是位于1112841位置的单个数字(在这种情况下为2
)。
如果我首先将我的GMP号码转换为带有mpz_get_str
的十进制数字字符串,我将不得不为这些数字分配大量内存,只使用它们中的一小部分并丢弃休息。 (更不用说二进制表示中的原始mpz_t
数字已经吃了很多。)
答案 0 :(得分:1)
我认为你不能在GMP中做到这一点。但是,您可以使用Boost Multiprecision Library
根据数字类型,精度可能是任意大的(仅限于可用内存),在编译时固定(例如50或100个十进制数字),或者在运行时控制的变量 - 成员函数的时间。这些类型是启用表达式模板的,以提供比天真的用户定义类型更好的性能。
强调我的
另一个替代方案是ttmath,其类型为ttmath::Big<e,m>
,您可以控制所需的精度。任何固定精度类型都可以使用,前提是您只需要最高位数,因为它们都会删除低有效数字,例如float
和double
的工作方式。这些数字不会影响结果的高位数,因此可以安全地省略。例如,如果您需要高20位数字,那么使用可以存储20位数字和更多数字的类型,以便提供足够的数据以便以后进行正确的舍入
为了演示,我们举一个7 7 = 823543的简单例子,你只需要前两位数字。使用4位数字型进行计算,您将获得此
正如您所看到的,即使不需要获得完整的结果,顶部数字也是相同的。使用GMP计算全精度不仅浪费了大量时间,还浪费了内存。考虑将另一个操作的结果存储在2个bigint上以获得所需数字所需的内存量。通过固定精度而不是将其保持在无穷大,您将显着降低CPU和内存使用量。
如果您需要第100到第200个高位数字,则使用具有足够空间容纳201位数字的类型,并在计算后提取这101个数字。但是这样会更浪费,所以你可能需要改为使用一个10的幂的基础的任意精度(或固定精度)类型(我正在使用GMP表示法)这里)。例如,如果类型使用基数10 9 ,则每个肢体代表十进制输出中的9位数,您可以直接获得十进制的任意数字,而无需从二进制到十进制的任何转换。这意味着对弦的零浪费。我不确定哪个库使用了基数10 n ,但你可以查看使用基数10 9 或Mini-Pi的write it yourself实现。这样它也可以有效地获得高位数
见
答案 1 :(得分:1)
如果您事先知道x = 7^1316831
的小数位数,例如1112852.那么您可以获得较低的,例如10位数:
x % (10^10)
,以及上面的20位数字:
x / (10^(1112852 - 20))
。
注意,我得到19821203202357042995
后者;最终为5
,而不是6
。