可能重复:
如何仅使用位移和加法进行乘法和除法?
我必须编写函数来执行二进制减法,乘法和除法,而不使用除循环控制之外的任何算术运算符.我之前只用Java编写代码,所以我很难绕过这个问题.
从减法开始,我需要用原型编写一个函数
int bsub(int x, int y)
Run Code Online (Sandbox Code Playgroud)
我知道我需要将y转换为二进制补码以使其为负数并将其添加到x,但我只知道如何通过使用一个补码运算符并添加1,但我不能使用+运算符.
提供了badd函数,如果我能弄清楚如何制作负数,我将能够在bsub中实现它.badd的代码如下所示.提前感谢任何提示.
int badd(int x,int y){
int i;
char sum;
char car_in=0;
char car_out;
char a,b;
unsigned int mask=0x00000001;
int result=0;
for(i=0;i<32;i++){
a=(x&mask)!=0;
b=(y&mask)!=0;
car_out=car_in & (a|b) |a&b;
sum=a^b^car_in;
if(sum) {
result|=mask;
}
if(i!=31) {
car_in=car_out;
} else {
if(car_in!=car_out) {
printf("Overflow occurred\n");
}
}
mask<<=1;
}
return result;
}
Run Code Online (Sandbox Code Playgroud) 我不能让2完成计算工作.
我知道C编译~b如果b = 5则将所有位反转为-6.但为什么?
int b = 101,反转所有位是010然后2完成符号我只加1但是变成011即3这是错误的答案.
我应该如何计算位反转算子〜?
类似的问题:如果a = 17,〜(~a)= 17怎么样?我们必须做两次完全计算.
二进制补码是当您反转位然后添加二进制1位数.所以例如......
0011001
apply two's complement
1. inverse the bits, 1100110
2. add a binary digit, 1100110 + 1 = 1100111
Run Code Online (Sandbox Code Playgroud)
另一个显示溢出情况的例子......
1001100
apply two's complement
1. inverse the bits, 0110011
2. add a binary digit, 0110011 + 1 = 0110100
Run Code Online (Sandbox Code Playgroud)
在python中实现它的最佳方法是什么.到目前为止,我有这个代码,但我希望它更有效,因为我太多使用这种方法.
def toTwosComplement(binarySequence):
convertedSequence = [0] * len(binarySequence)
carryBit = 1
# INVERT THE BITS
for i in range(0, len(binarySequence)):
if binarySequence[i] == '0':
convertedSequence[i] = 1
else:
convertedSequence[i] = 0
# ADD BINARY DIGIT 1
if convertedSequence[-1] == 0: …Run Code Online (Sandbox Code Playgroud) 如果我想将二进制数转换为32位二进制互补数.在javascript中这样做的正确方法是什么
e.g. "10101010001000101110101000101110" -> -1440552402
Run Code Online (Sandbox Code Playgroud)
而另一种方式?
e.g. -1440552402 -> "10101010001000101110101000101110"
Run Code Online (Sandbox Code Playgroud) #include <avr/io.h>
#include <avr/interrupt.h>
int main()
{
DDRB|=0x82;
DDRC=0x00;
DDRD=0xFF;
TCNT1H=(-640)>>8;
TCNT1L=(-640);
TCCR1A=0X00;
TCCR1B=0X01;
TIMSK=(1<<TOIE0)|(1<<TOIE1)
sei();
PORTD=PINC;
}
ISR(TIMER1_OVF_vect)
{
TCNT1H=(-640)>>8;
TCNT1L=(-640);
PORTB^=0X80;
}
Run Code Online (Sandbox Code Playgroud)
请帮我解决TCNT1H=(-640)>>8; TCNT1L=(-640);代码....因为我一直在使用0-256的值,所以真的很混乱....
我对比特操纵相当新,我想弄清楚(1 << 31) - 1是如何工作的.
首先我知道1 << 31是
1000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
而且我知道它实际上是最小int值的补充,但当我试图找出(1 << 31) - 1时,我发现一个解释说明,它只是
10000000000000000000000000000000 - 1 = 01111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
我几乎想要相信它,因为它真的很简单.但这真的发生了什么?如果不是,为什么它恰好是正确的?
我原来的想法是,真正的过程应该是:-1的两个补码是
11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
然后(1 << 31) - 1 =
(1)01111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
最左边的1被放弃,然后我们有int的最大值.
我真的很困惑哪一个是对的.
当我们对2的补码数进行乘法时,我很难理解为什么我们丢弃MSB.
我们以101(十进制:-3)和011(十进制:3)为例.算法是这样的:首先我们将数字的长度加倍,然后我们像在学校那样用小数进行通常的乘法,然后我们采用(加倍长度)*2 = 6个最低有效位.
双倍长度:
101 -> 111101
011 -> 000011
Run Code Online (Sandbox Code Playgroud)乘法:(
111101 * 000011 = 10110111十进制:-73)
如我们所见,这个结果是错误的.
10110111 -> 110111(十进制:-9)因此结果变得神奇地正确.怎么解释这个?我知道MSB有点特殊,我在学校使用的规则不能100%适合2的补充,但是虽然我完全理解学校的乘法规则,但我无法绕过2的最后一步.补码乘法(我理解前两步).
我已经读了两个关于溢出意味着什么的定义.
假设我们有以下添加:
11111111
00000001
--------
100000000
Run Code Online (Sandbox Code Playgroud)
我读过的第一个定义是结果不适合8位(在本例中需要9位)的事实,然后这称为溢出.
我读过的另一个定义是,如果我们有两个有符号整数的加法(例如两个补码整数):
10011001
10111011
--------
101010100
Run Code Online (Sandbox Code Playgroud)
然后,如果8位result(01010100)的符号与两个整数的符号不同(在本例中它是不同的),那么这称为溢出.
哪个定义是正确的?
根据二进制算术规则,我有8位int zero = 0b00000000;和8位int one = 0b00000001;,
0 - 1 = 1(从下一个有效位借1).
所以,如果我有:
int s = zero - one;
s = -1;
-1 = 0b1111111;
Run Code Online (Sandbox Code Playgroud)
所有这些1都来自哪里?有没有借到,因为所有位都0在zero变化.
在为使用GCC编译的小型ARM处理器编写软件时,我遇到了一个怪癖.处理器没有硬件分区引擎,因此分区是用软件实现的.
以下代码复制了行为,volatile语句用于避免优化:
volatile int32_t x = -4000;
volatile uint32_t y = 4;
volatile int32_t z = x / y;
uart_printf(DBG_LVL_INFO, "%d / %d = %d\r\n", x, y, z);
Run Code Online (Sandbox Code Playgroud)
为z打印的结果是1073740824,但我希望得到的结果-1000.
类型混合似乎很关键.替换uint32_twith int32_t可以解决bug.
-1000错误地解释为无符号整数不会产生结果,有趣地看起来等于结果加上2 30.
这是一个错误,还是只是定义了行为?