2

我被要求在不使用除法(/)和模数(%)的情况下将基数从 10 转换为 2 ,因此我想出了使用按位与(&)和右移(>>)运算符的解决方案。

因此,我开始了解这两个运算符的确切作用,但对于某些问题,我仍然无法找到答案或理解其背后的逻辑。

如果我理解正确除法是根据数字位值,十进制和二进制。当我们将数字除以 10 或 2 时,我们将位值向右移动一位,这将导致十进制除以 10,二进制除以 2。

X=120(以十为底)如果 X>>1 我们将有 X=12(除以 10)

Y=1000(以二为底)如果 Y>>1 我们将有 X=100(除以 2)

但是当我使用这段代码时:

#include<iostream>
using namespace std ;

int main()
{
    int a,b=1;
    cout <<"enter an integer"<<endl;
    cin>> a;
    cout<<(a & b)<<endl;
    a=a>>1;
    cout<<a;
    cout<<endl;
    system("pause");
    return 0 ;
}

我很困惑,因为在我的脑海里是这样的

a=120(以十为底)如果 X>>1 我们将有 X=12(除以 10)

但结果是这样的

a=120(以十为底)如果 X>>1 我们有 X=60(除以 2 !!)

我不明白关于结果的两个要点:

首先,如果这个操作符(>>)只是移动代码中数字的位置值而不改变数字(10)的基数,它应该产生另一个结果(12),而不是我们在代码结果中看到的(它是 60)。为什么我们可以看到这个结果(60)而不是 12?

其次,如果它进行二进制左移(对我来说似乎是这样),它是否首先通过 IDE 将十进制更改为二进制?

关于按位与,如果它是逻辑门(看起来是这样):

1.我们怎样才能把除了0和1之外的其他值,仍然有答案?

2.根据位与规则

Y&1=Y

那么它应该是 120 但代码的结果是 1。对此有何解释?

3.如何产生余数(根据哪些数学运算和逻辑)?

4

5 回答 5

6

C++ 中的移位运算符始终使用基数 2。也就是说,x >> 1将值移位x一位二进制数字。但是请注意,移位有符号整数并不是一个好主意,因为它们的值很容易未指定:在使用位逻辑时,您总是希望使用无符号整数,例如,unsigned intunsigned long。从十进制值到内部表示的转换是通过输入操作完成的,顺便说一句,需要检查是否成功:

if (std::cin >> a) {
     ...
}
else {
    std::cerr << "ERROR: failed to read value a\n";
}

另一个二元运算(&for and|for or^for _xor 和~for invert)对各个位进行操作。例如,7u & 13u产量5u。要获得除以 2 的幂的余数,您只需在除法之前使用合适的位掩码

顺便说一句,如果你想更好地了解这些人如何在二进制中工作,你可能想玩一下std::bitset<8>:这个类模板具有相同的按位运算,可以从整数构造,并且在打印时显示各个位。

于 2013-08-28T21:52:10.597 回答
4

>>C++ 中的运算符总是进行二进制移位,而不是十进制移位。没有小数移位运算符。如果需要,欢迎您编写自己的函数来执行此操作。

尽管将数学除以 10 视为移位一位小数并没有错,但这不是 C++ 的移位方式。此外,它正在向右移动,而不是向左移动——看看括号指向的方向。

您还误解了按位定义。当 Y 有点 时,Y & 1 = Y 是真的。当 Y 不止一位时,该定义被扩展为将一位定义应用于两个操作数中的一位。这就是按位的意思。运算符按位应用于操作数:左操作数的第一位与右操作数的第一位组合以产生结果的第一位。同样,两个操作数中的每一个的第二位确定结果的第二位,以此类推,以用于操作数中的每一对位。

要计算两个数相除的余数,请使用%运算符,也称为运算符。在你的 C++ 教科书中阅读更多关于它的信息。

于 2013-08-28T21:51:21.950 回答
1

当您读取输入时,cin >> a字符串“120”会转换为整数 120。在内存和 CPU 中,整数(可能取决于您的系统)表示为 32 位00000000 00000000 00000000 01111000。如果您使用 Windows,查看数字位模式的一种方便方法是程序员模式下的 Windows 计算器。

&操作按位进行。在 CPU 中有 32 个与门计算每个位位置的结果:

a     = 00000000 00000000 00000000 01111000
b     = 00000000 00000000 00000000 00000001
a & b = 00000000 00000000 00000000 00000000

所以结果是整数 0 而不是你写的 1。

另一个例子b=231: 结果是 96,只有位置 5 和 6 的位被设置,对于所有其他位置,至少一个输入位是 0。

a     = 00000000 00000000 00000000 01111000
b     = 00000000 00000000 00000000 11100111
a & b = 00000000 00000000 00000000 01100000

a = a>>1所有位向右移动一个位置之后。最左边的位会发生什么取决于符号,因此正如 Dietmar 建议的那样,最好使用无符号数据类型进行位操作。

a = 00000000 00000000 00000000 00111100

当您使用 打印结果时cout << a,此位模式将转换回十进制表示,作为字符串“60”。

于 2013-08-29T08:13:46.340 回答
1

<< 和 >> 运算符是按位运算符,它们以 2 为底“运算”。

http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23

http://www.cplusplus.com/doc/tutorial/operators/

于 2013-08-28T21:52:26.613 回答
0

通过按位移位,您使用的是二进制而不是十进制。

在内存中,120 以二进制形式存储 = 1111000 右移 1 = 111100 或 60

http://www.binaryhexconverter.com/binary-to-decimal-converter

演示转移: http: //www.miniwebtool.com/bitwise-calculator/bit-shift/

于 2013-08-28T21:55:44.987 回答