【问题标题】:Bit Operations, mainly ~位操作,主要是~
【发布时间】:2012-11-06 08:18:36
【问题描述】:

我目前正在将十进制转换为二进制,确保它是 8 位。除 ~ (NOT) 操作外,所有位操作均有效。它们以巨大的整数值出现。我不知道为什么,因为其他位操作有效。这是我的代码:(注释掉的行是不起作用的)

编辑:如果我想获得 8 位二进制字符串,我该怎么办?使用无符号字符?如果我将所有无符号整数更改为无符号字符,那么我的 BinaryToDecimal 函数会产生不正确的二进制转换。

#include <iostream>
#include <string>

using namespace std;

string BinaryToDecimal(unsigned int dec)
{
    string binary   = "";
    float remainder = 0.0f;

    while( dec != 0 )
    {
        remainder = dec % 2;
        dec      /= 2;

        if( remainder == 0 )
            binary.append("0");
        else
            binary.append("1");
    }


    // Reverse binary string
    string ret = string(binary.rbegin(), binary.rend());

    return ret;
}

int main()
{
    unsigned int a = 0;
    unsigned int b = 0;

    cout << "Enter a number to convert to binary: ";
    cin  >> a;
    cout << "Enter a number to convert to binary: ";
    cin  >> b;

    cout << "A = " << BinaryToDecimal(a) << endl;
    cout << "B = " << BinaryToDecimal(b) << endl;

    unsigned int c = a & b;
    unsigned int d = a | b;
    //unsigned int e = ~a;
    //unsigned int f = ~b;
    unsigned int g = a ^ b;
    unsigned int h = a << 2;
    unsigned int i = b >> 3;

    cout << "A & B  = " << BinaryToDecimal(c) << endl;
    cout << "A | B  = " << BinaryToDecimal(d) << endl;
    //cout << "~A     = " << BinaryToDecimal(e) << endl;
    //cout << "~B     = " << BinaryToDecimal(f) << endl;
    cout << "A ^ B  = " << BinaryToDecimal(g) << endl;
    cout << "A << 2 = " << BinaryToDecimal(h) << endl;
    cout << "B >> 3 = " << BinaryToDecimal(i) << endl;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果你对一个小的无符号整数执行二进制 NOT,你会得到一个很大的数字,因为大多数最高有效位将被设置为 1(它们在操作数中的倒数)。

    在这种情况下,您正在执行~ 0,这肯定会给您一个很大的数字,实际上是最大可能的无符号整数,因为所有位都将设置为 1。

    (你期待什么结果?)

    【讨论】:

    • 不,因为我输入的是一个数字,它不会是零。我期待如果我输入 5 (0101) 它会显示为 (1010)。
    • 仍然是正确答案。 5 存储为unsigned int,这意味着它至少为 0000000000000101
    • 好吧,如果我只尝试 8 位,我需要更改什么?
    • 最可靠的方法是屏蔽结果,即用 0xFF 与它。
    • @Cypras:您说了两次,但您的代码没有指定它“仅适用于 8 位”。
    【解决方案2】:

    您正在使用unsigned int 进行操作,由于从 MSB 开始的前导 1,小数的反转变成了大数。如果您只希望表示仅为 8 位,则应使用 unsigned char 进行存储。
    但是您不能将 a 或 b 更改为 unsigned char。否则,cin &gt;&gt; a 会将号码的 ASCII 码放入a,而不是数字。例如,您的输入是 5,它输入的是 0x35('5'),而不是数字 5。

    如果您不想更改代码的unsigned int,可以做一些小的改进

    string BinaryToDecimal(unsigned int dec)
    {
        string binary   = "";
        float remainder = 0.0f;
    
        dec &= 0xff;        // only 8 bits you care about
        while( dec != 0 )
        {
            ....
    

    但是您使用的是while( dec !=0 ),这是错误的。如果结果已经为 0,则该函数返回一个空字符串,而不是“0000”。相反,您应该使用计数器仅计数 8 位。

        for (int i = 0; i < 8; i++ ) {
            if ((dec & 1) != 0)
                binary.append("1");
            else
                binary.append("0");
            dec >>= 1;
        }
    

    另外,使用逐位AND 来测试位是0 还是1,以及移位操作,优于/ 和% 操作符。

    最后,对于 8 位 5 (0000_0101),它的反转是 250 (1111_1010),而不是 1010。

    【讨论】:

    • 您能解释一下增强代码是如何工作的吗?例如 dec&= 0xff; 是什么?做?还有 dec & 1 != 0 和 dec >>= 1。如果我想使用 unsigned char、unsigned char c = A & B,我需要做什么才能使其正常工作?
    • dec &amp;= 0xff 只会保留低 8 位。其他前导 1 将被消除,这样您的 while(dec != 0) 就不会产生一长串字符串。 dec &amp; 1 通过逐位 AND 操作检查 LSB 是 0 还是 1; dec &gt;&gt;= 1 将进行右移,例如,0101 变为 0010
    • 你能举一个 dec & 1 的例子吗?就像比较 5 和 1 一样,是比较 0101 和 1 还是什么?我不明白,仅此而已。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多