最常见的方法是为二进制数的每个非零位置获取2的幂,然后将它们相加。当二进制数很大时,这是不可行的,比如
10000 ... 0001 // 1000000个职位
不可能让计算机计算电量(2,1000000)。所以传统方式不可行。
其他方法吗?
有人可以提供有关如何计算的算术方法,不是库吗?
答案 0 :(得分:2)
正如happydave所说,这类事物有现有的库(如GMP)。如果由于某种原因需要自己动手,这里是一个合理有效的方法的概述。 你需要bigint减法,比较和乘法。
以二进制格式缓存10 ^(2 ^ n)的值,直到下一个值大于二进制数。这将允许您通过执行以下操作快速生成10的幂:
Select the largest value in your cache smaller than your remaining number, store this
in a working variable.
do{
Multiply it by the next largest value in your cache and store the result in a
temporary value.
If the new value is still smaller, set your working value to this number (swapping
references here rather than allocating new memory is a good idea),
Keep a counter to see which digit you're at. If this changes by more than one
between instances of the outer loop, you need to pad with zeros
} Until you run out of cache
This is your next base ten value in binary, subtract it from your binary number while
the binary number is larger than your digit, the number of times you do this is the
decimal digit -- you can cheat a little here by comparing the most significant bits
and finding a lower bound before trying subtraction.
Repeat until your binary number is 0
关于二进制数的大致为O(n ^ 4),关于存储器为O(nlog(n))。通过使用更复杂的乘法算法,您可以使n ^ 4更接近n ^ 3。
答案 1 :(得分:1)
您可以编写自己的类来处理任意大整数(可以表示为整数数组或任何最有意义的数组),并自己实现操作(*,pow等)。或者你可以谷歌“C ++大整数库”,并找到已经实现它的其他人。
答案 2 :(得分:1)
不可能让计算机计算电量(2,1000000)。所以传统方式不可行。
这不是不可能的。例如,Python可以立即进行算术计算,并在大约两秒钟内(在我的机器上)转换为十进制数。 Python内置了用于处理超出机器字大小的大整数的工具。
在C ++(和C)中,大整数库的一个很好的选择是GMP。它功能强大,经过良好测试并得到积极维护。它包含一个C++ wrapper,它使用运算符重载来提供一个很好的接口(除了pow()
操作没有C ++运算符)。
以下是使用GMP的C ++示例:
#include <iostream>
#include <gmpxx.h>
int main(int, char *[])
{
mpz_class a, b;
a = 2;
mpz_pow_ui(b.get_mpz_t(), a.get_mpz_t(), 1000000);
std::string s = b.get_str();
std::cout << "length is " << s.length() << std::endl;
return 0;
}
以上的输出是
length is 301030
在0.18秒内在我的机器上执行。
答案 3 :(得分:1)
&#34;关于二进制数字的大致为O(n ^ 4),关于存储器&#34;为O(nlog(n))。您可以执行O(n ^(2 + epsilon))运算(其中n是二进制数字的数量)和O(n)存储器,如下所示:设N是一个巨大数量的二进制长度n。计算残差mod 2(容易;抓住低位)和mod 5(不容易但不可怕;将二进制字符串分成四位的连续字符串;计算每个这样的4元组的残差mod 5,并将它们加起来与为十进制数输出9'相同。)通过计算残差mod 2和5,您可以读取低十进制数字。减去这个;除以10(互联网记录这样做的方法),并重复以获得次低的数字。
答案 4 :(得分:0)
我在Smalltalk中计算了2 ** 1000000并在9.3秒内将其转换为十进制,所以这不是不可能的。 Smalltalk内置了大型整数库。
2 raisedToInteger: 1000000
如另一个答案所述,您需要一个处理任意精度整数的库。一旦你有了它,你就可以对它进行MOD 10和DIV 10操作,以相反的顺序计算十进制数字(最重要的是最重要的)。
粗略的想法是这样的:
LargeInteger *a;
char *string;
while (a != 0) {
int remainder;
LargeInteger *quotient;
remainder = a % 10.
*string++ = remainder + 48.
quotient = a / 10.
}
这里有许多关于类型转换,内存管理和对象分配的细节缺失(或错误),但它的目的是演示一般技术。
答案 5 :(得分:0)
使用Gnu Multiprecision Library非常简单。不幸的是,我无法测试这个程序,因为我似乎需要在编译器升级后重建我的库。但是没有太大的错误空间!
#include "gmpxx.h"
#include <iostream>
int main() {
mpz_class megabit( "1", 10 );
megabit <<= 1000000;
megabit += 1;
std::cout << megabit << '\n';
}