首页 > 编程知识 正文

python实现 -十进制转二进制,python怎么把十进制转二进制

时间:2023-05-06 18:41:13 阅读:241362 作者:2747

1原理 1.1 正数

十进制下:5 + 7 = 12

5: 0101

7: 0111

二进制下两数求和,分三步:

各位值相加,不算进位值,二进制亦或运算计算进位值,二进制与运算,然后左移一位;对1,2步的结果,重复以上两步骤

两数之和就是不计算进位值加上进位值,直到没有进位

第二部为什么要左移?

jjdxtg在十进制下计算5+7时,进位向前一位进1,也就是相当于左移

5 + 7的详细计算:

第一次:

亦或:0101^0111 = 0010,没有进位的值。

与:0101&0111 = 0101,等于1的位说明这一位是要产生进位的。而进位是要向前进一位,所以要左移

0101 ,两个位置为1,说明是有两个位置需要进位,左移运算,0101<<1 = 1010

第二次:

0010^1010 = 1000

(0010&&1010)<<1 = 0100 # 还有进位,需要继续加

第三次:

1000^0100 = 1100

(1000&&0100) <<1= 0000 # 没有进位

进位为0,返回第一步的结果。

1.2 负数

博客上好多教程都是以正数为例来解释,让好多读者误认为二进制的运算是在源码上进行的。

实际情况是用补码运算的!!!

因为正数的源码、反码、补码是相等的,所以大家误认为是用的源码。

python3 中最高位1表示负数,最高位0表示正数

(个人认为,用补码运算是因为可以把符号位直接参与运算)

源码转化成补码:源码转化成反码(符号位1不变,其他位改变),然后反码+1

补码转化为源码:你只需要记住,补码的补码就是源码

所以补码转反码,然后+1

例如 -2 + 8

用8位二进制表示:

-2 源码 :1000 0010;反码:1111 1101;补码:1111 1110

8 源码/反码/补码:0000 1000

用补码运算结果如下:

1、1111 1110^0000 1000 = 1111 0110 (负数)转化成源码:1000 1010 = -10

2、(1111 1110&0000 1000)<<1 = 0001 0000 (正数),源码和补码一样:0001 0000 = 16

这是用补码运算的例子。

继续运算:

进位为16,继续计算1,2步,你会发现进入死循环。

因为:python3实现不会溢出,溢出的最高位不会舍弃掉。详细请看博文:https://www.jianshu.com/p/21fd1598d4ae

这种方法在c,c++,java中没有问题。但在python3中会有问题,python3存的正数是无限大的

2 python代码

python位运算

与 &    或 |     非 ~     亦或 ^      左移 <<         右移 >>

# -*- coding:utf-8 -*-class Solution: def Add(self, num1, num2): # write code here if not num1: return num2 elif not num2: return num1 while num2: num1,num2 = (num1^num2)&0xFFFFFFFF, (num1&num2)<<1 if num1>>31 ==0: return num1 else: return num1 - 4294967296

为什么还要 - 4294967296,因为2**32 =  - 4294967296。

下面详细解释:

回到前面:

咱们计算两个数相加是用的二进制,而且是二进制的补码,

如果直接输出就是把补码直接转化成十进制(中间没有转化成反码+1)。

但是我们最后要输出的是源码的十进制,所以中间少了一步转化成源码的步骤。

之前的计算:1111 1110^0000 1000 = 1111 0110 (负数)转化成源码:1000 1010 = -10

1111 0110 直接转化成十进制是246,而我们想要的结果是-10

你会发现246-256 = -10,这就是我们的结果。

为什么减去256,和我们的位数8有关,2**8 = 256

在程序中,我们用的是32位,所以减去2**32.

而正数因为源码,反码,补码都相等就不会出现这个问题。

 

查了好久的资料终于解决问题了,吃饭去了!!!

margin

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。