我有一些我写的代码,这些代码将成功地返回我一个二进制号码。例如,以101输入运行下面的代码将返回5。但是,当我在MSB的左侧添加0位时出现问题,因此不会更改值。当我将0101输入系统时,我应该期望再次返回5,但它返回17。
这是我的代码:
int dec1 = 0, rem1=0, num1, base1 = 1;
int a = 101;
while (a > 0){
rem1 = a % 10;
dec1 = dec1 + (rem1 * base1);
base1 = base1 * 2;
a = a / 10;
}
cout << dec1 << endl;
输出是5。正确。
但是,当" A"更改为0101时,输出变为17。我相信我的错误与对Modulo Operator的误解有关。
101%10 = 1对吗?编译器通常以相同的方式读取0101%10吗?
我在我的代码中添加了一个COUT语句,以查看计算0101%10的值后,在REM1中存储了什么值。
int dec1 = 0, rem1=0, num1, base1 = 1;
int a = 101;
while (a > 0){
rem1 = a % 10;
cout << rem1 << endl;
dec1 = dec1 + (rem1 * base1);
base1 = base1 * 2;
a = a / 10;
}
cout << dec1 << endl;
从中,我能够看到计算0101%10之后,值5的值存储在rem1中,而不是1。
。在MSB的前面添加这个0是否告诉编译器"嘿,这个数字在二进制中?"因为如果编译器正在读取5%10而不是0101%10,那么我想错误是有道理的。
测试我的理论后,我将" A"更改为1000,输出为8,这是正确的。
将'a'更改为01000的结果为24。rem1 = 01000%10应该为0,但是rem1存储2. 01000二进制= 8小数。8%10 = 8?不是2?
我不确定正在发生的事情,并感谢任何帮助!
101
被解析为十进制(基本10(数字,因此您获得了预期的输出。
0101
由于领先零而被解析为八十八个数字(基数8(。这里的领先零就像指的是指示十六进制(基本16(数字的领先的0x
前缀一样,除了没有x
,它的基本8而不是基础16。†
101 8 = 8 2 8 0 = 64 1 = 65
65%10 = 5
65/10 = 6
6%10 = 7
5 * 2 7 = 17
如果我是您,则在分配后,我会在rem1
内立即在您的循环中添加assert(rem1 == 0 || rem1 == 1)
,作为理智检查。如果您的剩余时间大于一个或小于零,那么显然是错误的。
正如rbaleksandar在上面的评论中指出的那样,避免此问题的最简单方法可能是将您的输入存储为C弦乐(char[]
(,而不是使用整数文字。这也很好,因为您可以迭代字符以计算值而不是进行%
和/
操作。
另外,您可以在所有输入中使用十六进制文字(例如0x101
或0x0101
(,然后将数学更改为使用基础16而不是基础10。这具有额外的优势,即基本10分部和剩余功能可以是由于16的功率为2(例如,0x101 % 16
==> 0x101 & 15
,并且0x101 / 16
==> 0x101 >> 4
(。
†有关更多信息 请参阅http://en.cppreference.com/w/cpp/language/integer_literal
0101是八进制号,值为17。