【问题标题】:Converting many bits to Base 10将许多位转换为 Base 10
【发布时间】:2013-10-22 05:52:14
【问题描述】:

我正在用 C++ 构建一个可用于存储任意大整数的类。我将它们作为二进制存储在向量中。我需要能够以 10 为基数打印此向量,以便人类更容易理解。我知道我可以将其转换为 int,然后输出该 int。但是,我的数字将比任何原始类型大得多。如何将其直接转换为字符串。

到目前为止,这是我的代码。我是 C++ 新手,所以如果您有任何其他建议也很好。我需要帮助填写string toBaseTenString() 函数。

class BinaryInt
{
private:
    bool lastDataUser = true;
    vector<bool> * data;
    BinaryInt(vector<bool> * pointer)
    {
        data = pointer;
    }
public:
    BinaryInt(int n)
    {
        data = new vector<bool>();
        while(n > 0)
        {
            data->push_back(n % 2);
            n = n >> 1;
        }
    }
    BinaryInt(const BinaryInt & from)
    {
        from.lastDataUser = false;
        this->data = from.data;
    }
    ~BinaryInt()
    {
        if(lastDataUser)
            delete data;
    }
    string toBinaryString();
    string toBaseTenString();
    static BinaryInt add(BinaryInt a, BinaryInt b);
    static BinaryInt mult(BinaryInt a, BinaryInt b);
};
BinaryInt BinaryInt::add(BinaryInt a, BinaryInt b)
{
    int aSize = a.data->size();
    int bSize = b.data->size();
    int newDataSize = max(aSize, bSize);
    vector<bool> * newData = new vector<bool>(newDataSize);
    bool carry = 0;
    for(int i = 0; i < newDataSize; i++)
    {
        int sum = (i < aSize ? a.data->at(i) : 0) + (i < bSize ? b.data->at(i) : 0) + carry;
        (*newData)[i] = sum % 2;
        carry = sum >> 1;
    }
    if(carry)
        newData->push_back(carry);
    return BinaryInt(newData);
}
string BinaryInt::toBinaryString()
{
    stringstream ss;
    for(int i = data->size() - 1; i >= 0; i--)
    {
        ss << (*data)[i];
    }
    return ss.str();
}
string BinaryInt::toBaseTenString()
{
    //Not sure how to do this
}

【问题讨论】:

  • 你不想在这里使用std::vector&lt;bool&gt;,你也不需要指向向量的指针。像std::vector&lt;unsigned&gt; data; 这样的东西,加上一个额外的标志标志,将是最简单的。
  • 对于转换,您需要实现/%(最好使用intBinaryInt)。
  • 为什么我不想使用指针?如果我存储了这么多数据,它不应该放在堆栈上。我还认为使用这一点可以使复制我的课程更加高效,因为我不必复制数据。
  • vector&lt;bool&gt; 的大小并不是特别大,不管它包含多少元素。对于像BinaryInt 这样的东西,你需要值语义。

标签: c++ math binary numbers largenumber


【解决方案1】:

我知道你在 OP 中说过“我的数字将比任何原始类型都大”,但请听我说完。

过去,我使用 std::bitset 处理数字的二进制表示,并从各种其他表示来回转换。 std::bitset 基本上是一个带有一些附加功能的花哨的 std::vector。如果这听起来很有趣,您可以阅读更多关于它的信息here,但这里有一些愚蠢的小示例代码向您展示它是如何工作的:

std::bitset<8> myByte;

myByte |= 1;  // mByte = 00000001
myByte <<= 4; // mByte = 00010000
myByte |= 1;  // mByte = 00010001

std::cout << myByte.to_string() << '\n';  // Outputs '00010001'
std::cout << myByte.to_ullong() << '\n';  // Outputs '17'

您也可以通过标准数组表示法访问位集。顺便说一句,我展示的第二次转换 (to_ullong) 转换为 unsigned long long,我相信它的最大值为 18,446,744,073,709,551,615。如果您需要更大的值,祝您好运!

【讨论】:

    【解决方案2】:

    只需迭代(向后)您的vector&lt;bool&gt; 并在迭代器为真时累积相应的值:

    int base10(const std::vector<bool> &value)
    {
        int result = 0;
        int bit = 1;
    
        for (vb::const_reverse_iterator b = value.rbegin(), e = value.rend(); b != e; ++b, bit <<= 1)
            result += (*b ? bit : 0);
    
        return result;  
    }
    

    Live demo.

    小心!此代码仅供参考,如果值很大,您需要注意 int 溢出。

    希望对你有帮助。

    【讨论】:

    • 这行得通,但是,我将处理数百万位。我需要跳过转换为和 int 并直接转到字符串。
    猜你喜欢
    • 2011-01-24
    • 2012-03-22
    • 2018-03-09
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 2014-12-07
    相关资源
    最近更新 更多