如何将无限长度的二进制转换为十进制
How to convert unlimited length binary to decimal
最常见的方法是得到二进制数的每个非零位置的 2 的幂,然后将它们相加。当二进制数很大时,这是行不通的,比如说,
10000...0001//1000000 个仓位
不可能让计算机计算 pow(2,1000000)。所以传统方式是行不通的。
其他方法可以做到这一点?
有人可以给出一个关于如何计算的算术方法,而不是库吗?
正如Happydave所说,这种类型的事情已经存在库(如GMP)。如果您出于某种原因需要自己动手,这里有一个相当有效的方法的概述。你需要大减法、比较和乘法。
以二进制格式缓存值 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。
您可以编写自己的类来处理任意大的整数(您可以将其表示为整数数组或任何最有意义的整数),并自己实现操作(*,pow 等)。 或者你可以谷歌"C++大的整数库",并找到已经实现它的其他人。
不可能让计算机计算 pow(2,1000000)。所以传统方式是行不通的。
这并非不可能。例如,Python可以立即进行算术计算,并在大约两秒钟内转换为十进制数(在我的机器上)。Python内置了处理超过机器字大小的大整数的工具。
在C++(和C)中,大整数库的一个不错的选择是GMP。它坚固耐用,经过良好测试,并积极维护。它包括一个C++包装器,该包装器使用运算符重载来提供漂亮的接口(除了,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;
}
上述输出为
长度为 301030
在我的机器上执行 0.18 秒。
"这大约是关于二进制位数的O(n^4),关于内存的O(nlog(n))"。 您可以执行 O(n^(2 + epsilon)) 操作(其中 n 是二进制位数)和 O(n) 内存,如下所示:设 N 是大量二进制长度 n。计算残基 mod 2(容易;抓住低位)和 mod 5(不容易但不可怕;将二进制字符串分解成四个位的连续字符串;计算每个这样的 4 元组的残基 mod 5,并将它们相加,就像为十进制数抛出 9 一样。通过计算残基 mod 2 和 5,您可以读出低十进制数字。 减去这个;除以 10(互联网记录了执行此操作的方法),然后重复以获得下一个最低的数字。
我在 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.
}
这里缺少(或错误)了许多关于类型转换、内存管理和对象分配的细节,但它旨在演示一般技术。
使用 Gnu 多精度库非常简单。不幸的是,我无法测试这个程序,因为似乎我需要在编译器升级后重建我的库。但是没有太多的错误余地!
#include "gmpxx.h"
#include <iostream>
int main() {
mpz_class megabit( "1", 10 );
megabit <<= 1000000;
megabit += 1;
std::cout << megabit << 'n';
}
- C++从二进制转换为十进制数
- 我写的 ASCII 到二进制转换器C++向后显示二进制,如何使其正确显示?
- 十进制到二进制转换器 c++
- 将二进制转换为十进制,我如何要求用户仅输入二进制
- 十进制,包括负到 32 位二进制转换器
- 输入 1024 后十进制到二进制转换的输出错误?
- C 二进制转换为双精度的转换运算符
- 将二进制转换为负整数
- 如何将 32 位编译二进制转换为 64 位
- 如何在 C++ 中将二进制转换为十六进制
- 如何理解 c++ 中的 MNIST 二进制转换器?
- 以下对二进制转换代码的小数如何工作
- 具有递归功能的二进制转换给出一个奇数值
- 了解C++位操作中的二进制转换实现
- 编写将二进制转换为文本C 6的程序
- 反射格雷码到二进制转换中的幻数
- 为什么我总是必须除以 49 才能得到二进制转换器 + cout 歧义的正确答案?
- 如何使用库将二进制转换为十进制<bitset>?
- C++二进制转换为十进制,八进制
- 脚本到二进制转换和对象序列化