1

我正在使用 GNU 多精度 (GMP) 库对任意精度整数执行一些计算。然后我需要结果的十进制数字。但不是全部:只是,比方说,一百个最高有效数字(即数字开头的数字)或数字中间的选定数字范围(例如 1000 中的数字 100..200 -数字)。

GMP有什么办法吗?

我在文档中找不到任何函数来提取一系列十进制数字作为字符串。mpz_t转换为字符串的转换函数总是转换整数。只能指定基数,但不能指定起始/结束数字。

除了将整个数字转换成一个巨大的字符串,只取一小部分并扔掉其余部分之外,还有什么更好的方法吗?

编辑:我需要的不是控制我的数字的精度或将其限制为特定的固定位数,而是从任意精度的数字字符串中选择一个数字子集。

这是我需要的一个例子:

7 1316831 = 19821203202357042996...2076482743

实际数字有 1112852 位,我将其收缩到....
现在,我只需要这个庞大的数字字符串中任意选择的子字符串。例如,十个最高有效数字(1982120320在这种情况下)。或者从 1112841到 1112849数字21203202在这种情况下)。或者在第 1112841个位置(2在这种情况下)只有一个数字。

如果我首先用 将我的 GMP 数字转换为一串十进制数字mpz_get_str,我将不得不为这些数字分配大量内存,只使用其中的一小部分并丢弃其余数字。(更不用说mpz_t二进制表示的原始数字已经吃掉了很多。)

4

2 回答 2

1

如果您事先知道小数位数x = 7^1316831,例如 1112852。那么您会得到较低的,例如 10 位数字:

x % (10^10),以及上面的 20 位数字:

x / (10^(1112852 - 20)).

注意,我19821203202357042995支持后者;5最后,不是6

于 2015-01-27T11:25:46.020 回答
1

我认为你不能在 GMP 中做到这一点。但是,您可以使用Boost 多精度库

根据数字类型,精度可以任意大(仅受可用内存限制),在编译时固定(例如 50 或 100 个十进制数字),或者在运行时由成员函数控制的变量。这些类型启用了表达式模板,以获得比天真的用户定义类型更好的性能。

强调我的

另一种选择是ttmath类型ttmath::Big<e,m>,您可以控制所需的精度。只要您只需要最重要的数字,任何固定精度类型都可以使用,因为它们都会删除低有效数字,例如如何floatdouble工作。这些数字不会影响结果的高位,因此可以安全地省略。例如,如果您需要高 20 位,则使用可以存储 20 位及更多位的类型,以便为以后正确舍入提供足够的数据

为了演示,让我们以 7 7 = 823543 的简单示例为例,您只需要前 2 位数字。使用 4 位类型进行计算,您将得到这个

  • 7 5 = 16807 => 舍入到 1681×10¹ 并存储
  • 7 5 ×7 = 1681×10 1 ×7 = 11767*10¹ ≈ 1177×10 2
  • 7 5 ×7×7 = 1177×10 2 ×7 = 8232×10 2

正如您所看到的,即使不需要获得完整的精确结果,顶部的数字也是相同的。使用 GMP 计算全精度不仅浪费大量时间,而且还浪费内存。考虑在 2 个 bigint 上存储另一个操作的结果以获得所需数字所需的内存量。通过固定精度而不是将其保持在无限,您将显着降低 CPU 和内存使用量。

如果您需要第 100到第 200高位数字,请使用有足够空间容纳 201 位及更多位的类型,并在计算后提取这 101 位数字。但这会更加浪费,因此您可能需要更改为任意精度(或固定精度)类型,该类型使用其四肢的 10 次方的基数(我在这里使用 GMP 表示法)。例如,如果类型使用以 10 9为基数,则每个肢体代表十进制输出中的 9 位数字,您可以直接获得十进制中的任意数字,而无需任何从二进制到十进制的转换。这意味着字符串的零浪费。我不确定哪个库使用 base 10 n但您可以查看Mini-Pi的使用 base 10 的实现9、还是自己写吧。这样它也可以有效地获得高位数字

于 2015-01-27T10:25:56.690 回答