将向量<bool>转换为十进制(作为字符串)
convert vector<bool> to decimal (as string)
使用这个函数可以很容易地将vector转换为十进制(整数):
vector<bool> A = {0, 1, 1, 1,0,1}; # A size will change during run time
long int integer = 0, n = 0;
for (auto i : A)
{
if (i)
{
integer += pow(2, n);
}
n = n + 1;
}
但是如果vector的元素数超过64个,则结果将不可预测。
我们如何写类似的函数,但返回字符串代替?
正如其他人所建议的,对于表示任何固定长度的二进制数(对于动态长度,如您的情况,请参阅boost::dynamic_bitset
),使用std::bitset
是更好的选择。这个链接解释了为什么不使用std::vector<bool>
的一些原因。
你的问题基本上可以归结为实现一个BigNum类。就像您在方法中所做的一样,首先需要将值从二进制转换为十进制(但现在需要64位以上的精度)。一旦构造了BigNum,将其转换为字符串就很简单了。我通过简单地修改前一段时间制作的BigNum
类来实现您要求的算法。
要打印二进制数,以下几行应该足够了。
/*Creates a 90-digit binary number with all bits set.*/
std::vector<bool> A(90, 1);
/*Prints its decimal reprsentation*/
cout << longBinaryToDecimalAsString(A);
至于实现:
#ifndef BIG_NUM_H
#define BIG_NUM_H
#include <string>
#include <vector>
#include <sstream>
#include <cstdint>
class BigNum {
public:
BigNum(){values.push_back(0);}
BigNum(std::uint64_t val){
if (val == 0)
values.assign(1, 0);
else{
while (val > 0){
values.push_back(val % 10);
val /= 10;
}
}
}
BigNum &operator+=(BigNum &rhs)
{
std::vector<std::uint8_t> *lowAddend, *bigAddend;
/*If right value is larger, ‘values’ vector will always grow*/
if (rhs.values.size() > values.size()){
values.resize(rhs.values.size(), 0);
lowAddend = &values;
bigAddend = &rhs.values;
}
else{
values.push_back(0);
bigAddend = &values;
lowAddend = &rhs.values;
}
std::uint8_t carry = 0;
size_t i = 0;
/*First we sum lower part*/
for (; i < lowAddend->size(); ++i){
std::uint8_t sum = values[i] + rhs.values[i] + carry;
values[i] = sum % 10;
carry = sum / 10;
}
/*Now we copy the remaining part*/
for (; i < bigAddend->size(); ++i){
/*For 10 10, sum will be 18, at most*/
std::uint8_t sum = (*bigAddend)[i] + carry;
values[i] = sum % 10;
carry = sum / 10;
}
this->trimFrontalZeros();
return *this;
}
BigNum &operator*=(BigNum &rhs)
{
/*Case when one of the operands is Zero*/
if (this->isZero())
return *this;
else if (rhs.isZero()){
values.assign(1, 0);
return *this;
}
size_t maxLen = values.size() + rhs.values.size();
std::vector<std::uint8_t> product(maxLen);
size_t lowSize, bigSize;
std::vector<std::uint8_t> *multiplier, *multiplicand;
/*The iteration process for the multiplicaiton is developed as the multiplier (A in A*B)
as the one with more digits.*/
if (values.size() > rhs.values.size()){
multiplier = &values;
multiplicand = &rhs.values;
bigSize = values.size();
lowSize = rhs.values.size();
}
else{
multiplier = &rhs.values;
multiplicand = &values;
bigSize = rhs.values.size();
lowSize = values.size();
}
/*Implemented as 'values x rhs.values' */
std::uint8_t carry = 0;
for (size_t n = 0; n < maxLen; ++n){
size_t numIters;
if (maxLen - n - 1< lowSize) numIters = maxLen - n - 1;
else numIters = std::min(n + 1, lowSize);
std::uint64_t sum = 0;
for (size_t i = 0; i < numIters; ++i){
size_t indBelow = i + n + 1 - std::min(n + 1, lowSize);
size_t indAbove = std::min(n + 1, lowSize) - 1 - i;
std::uint8_t be = (*multiplier)[indBelow];
std::uint8_t ab = (*multiplicand)[indAbove];
sum += be*ab;
}
sum += carry;
product[n] = sum % 10;
carry = sum / 10;
}
values.assign(product.begin(), product.end());
this->trimFrontalZeros();
return *this;
}
std::string toString(){
std::stringstream ss;
std::copy(values.rbegin(), values.rend(), std::ostream_iterator<int>(ss, ""));
return ss.str();
}
private:
bool isAbsOne() {return values.size() == 1 && values[0] == 1;}
bool isZero() {return values.size() == 1 && values[0] == 0;}
void trimFrontalZeros(){
size_t newSize = values.size();
auto it = values.rbegin();
while (it != values.rend() && *it == 0){
++it;
--newSize;
}
values.resize(newSize);
}
std::vector<std::uint8_t> values;
};
std::string longBinaryToDecimalAsString(std::vector<bool> &longBinary){
BigNum big;
std::uint64_t n = 0;
for (bool bit : longBinary){
if (bit){
if (n > 63){
BigNum aux(1);
for (std::uint64_t i = 0; i < n / 32; ++i){
aux *= BigNum(1ULL << 32);
}
aux *= BigNum(1ULL << (n % 32));
big += aux;
}
else{
big += BigNum(1ULL << n);
}
}
++n;
}
return big.toString();
}
#endif
请注意这是BigNum
类的一个非常简化的版本。将其用于本问题之外的其他目的可能会输出不希望的结果。例如,它不考虑+
和*
操作的负数
相关文章:
- 将字符串(可以是十进制字符串或十六进制字符串)转换为整数C++
- 使用标准库计算字符串中的十进制数
- 如何在C ++中将二进制字符串128位转换为十进制字符串?
- 十进制到八进制递归C++.以标准::字符串格式输出
- 如何将带有浮点数的字符串转换为十进制?
- C++十进制到十六进制(字符串下标超出范围)
- 以C++格式将十六进制字符串转换为十进制数
- 将二进制字符串转换为十进制
- 使用堆栈将字符串格式的十进制转换为双精度
- 字符串到 Unicode,Unicode 到十进制码位 (C++)
- 如何使用C 将二进制数字的字符串转换为其签名的十进制表示
- C 如何将双重转换为字符串,因此它仅在十进制后显示2位数字
- C++:二进制标准::字符串到十进制
- 如何将数字转换为十进制字符串
- C++覆盖用户输入双倍为十进制字符串
- C++ 将十进制字符串拆分为两个整数
- 将十六进制二进制或十进制字符串转换为长整型字符串C++
- CRYPT_INTEGER_BLOB转换为十进制字符串
- Arduino:从两个十进制字符串中获取十六进制值
- 如何将十进制字符串转换为二进制字符串