1. 程式人生 > >不用加減乘除做加法中Python存在的bug

不用加減乘除做加法中Python存在的bug

今天在刷《劍指offer》的時候,在做面試題47的時候,碰到了一道題:

寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。

題目本身也不太難,使用位的異或運算和 位與操作即可。程式碼如下:

class Solution:
    def Add(self, num1, num2):
        while num2:
            sum = num1 ^ num2
            carry = (num1 & num2) << 1
            num1 = sum
            num2 = carry
        return
num1

但是我在測試用例的時候,選擇了一個4, 一個-2, 發現很久都沒有打印出結果。於是我就嘗試按步驟分析一個正數和一個負數的位運算,發現在這個過程中,sum = num1 ^ num2這句話中,在不斷的迭代中變成了一個越來越小的負數, 這時候我大約猜出來了不出結果的原因了。
因為在python早期版本中如Python2.7中,整數的有int和long兩個型別。int型別是一個固定位數的數;long則是一個理論上可以儲存無限大數的資料型別。當數大到可能溢位時,為了避免溢位,python會把int轉化為long。而Python3.x之後整數只有一個可以放任意大數的int了。可是無論哪種,都是採用了特殊的方法實現了不會溢位的大整數。
因此,在計算正數和負數異或的時候,Python就會不斷的算啊算,算啊算。。。

之後我利用Swift模擬了一下,畢竟強大的Swift可以直接顯示出中間計算的結果,測試用例還是4和-2。直接上圖:

執行結果

異或結果截圖如下所示:

sum

異或sum取的值如下所示,也能夠更直觀的看出來,在計算一個正數和負數進行按位加法的時候,必須要先溢位才能求得正確的答案:

-6
-14
-30
-62
-126
-254
-510
-1022
-2046
-4094
-8190
-16382
-32766
-65534
-131070
-262142
-524286
-1048574
-2097150
-4194302
-8388606
-16777214
-33554430
-67108862
-134217726
-268435454 -536870910 -1073741822 -2147483646 -4294967294 -8589934590 -17179869182 -34359738366 -68719476734 -137438953470 -274877906942 -549755813886 -1099511627774 -2199023255550 -4398046511102 -8796093022206 -17592186044414 -35184372088830 -70368744177662 -140737488355326 -281474976710654 -562949953421310 -1125899906842622 -2251799813685246 -4503599627370494 -9007199254740990 -18014398509481982 -36028797018963966 -72057594037927934 -144115188075855870 -288230376151711742 -576460752303423486 -1152921504606846974 -2305843009213693950 -4611686018427387902 -9223372036854775806 2

綜上所述,可以知道:Python搞東西確實方便,但是效率很低,讓容納很大的數確實省去了考慮大數的煩惱,但是事出反常必有妖,這個不能溢位有時候也很鬧人啊。。。。

相關推薦

不用乘除加法Python存在的bug

今天在刷《劍指offer》的時候,在做面試題47的時候,碰到了一道題: 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 題目本身也不太難,使用位的異或運算和 位與操作即可。程式碼如下: class Solutio

劍指offer python不用乘除加法

pre bsp car off offer return pan def style def add(n,m): while m: summ=n^m carry=(n&m)<<1 m=carry

劍指offer---不用乘除加法

logs class int col clas off urn turn spa class Solution { public: int Add(int num1, int num2) { while (num2--) {

劍指offer42:不用乘除加法

pla -m == spa 都是 cli class offer 十進制 分析: (1)十進制加法分三步:(以5+17=22為例) 1. 只做各位相加不進位,此時相加結果為12(個位數5和7相加不進位是2,十位數0和1相加結果是1); 2. 做進位,5+7中有進位,進位的

48不用乘除加法

while 左移 public 一位 位運算 div class 循環 進位 題目描述 寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。 利用位運算 1、2個數異或,相當於每一位相加,不考慮進位 2、2個數相與並左移一位,相當於 求進位

劍指Offer - 不用乘除加法

sub 題目 return 加減乘除 describe body col style blog 題目描述 寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號. 代碼: class Solution { public: int

一道算法題-不用乘除加法

ren 位數 位運算 turn article 算法題 交換 clas aot 題目:   寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。 解析①:   首先看十進制是如何做的: 5+7=12,三步走 第一步:相加各位的值,不算進位,得到

劍指offer——不用乘除加法

不用 odin www coder rank page -i offer quest 不用加減乘除做加法 不會劍指offer——不用加減乘除做加法

不用乘除加法

與運算 int ret 步驟 urn 兩個 加減乘除 plus 要求 題目:寫一個函數,求兩個整數之和,要求在函數體內不得實用+、-、x、%四則運算符。 接下來我們試著把二進制的加法用位運算來替代。第一步不考慮進位對每一位相加。0加0、1加1的結果都為0,0加1、1加0的結

劍指offer第65:不用乘除加法

題目描述 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 # -*- coding:utf-8 -*- class Solution: def Add(self, num1, num2): # write code here

劍指offer——不用乘除加法(按位與和異或)

class Solution { public: int Add(int num1, int num2) { while(num2 != 0){//若需要進位 int sum = num1 ^ num2;//異或,01=1,00=0,11=

劍指offer系列(十七)求1+2+3+...+n,不用乘除加法,把字串轉換成整數

求1+2+3+...+n 題目描述 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。 解題思路: 法一:利用python的特性 法二:用兩個函式,一個遞迴,另一個終止遞迴。如果對n連續進

劍指offer____不用乘除加法

寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 方法一:位運算 class Solution { public: int Add(int num1, int num2) { /* if(num2 == 0) r

劍指Offer之不用乘除加法

題目描述 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 思路 異或和移位操作。 AC程式碼 class Solution { public: int Add(int num1, int num2) {

劍指offer 48. 不用乘除加法

原題 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 Reference Answer 思路分析 首先看十進位制是如何做的: 5+7=12,三步走 第一步:相加各位的值,不算進位,得到2。 第二步:計算進位值,得到10. 如果

D-位運算-劍指Offer(Java版)47-不用乘除加法

題目 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 位操作 與(&) 或(|) 非(~) 異或(^) 左移(<<) :num << 1,相當於num乘以2 右移(>>) :num

(劍指offer)不用乘除加法

時間限制:1秒 空間限制:32768K 熱度指數:83474 題目描述 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號 程式碼1: public class Solution { public int Add(int num1,int n

《劍指offer》-- 構建乘積陣列、求1+2+3+...+n、不用乘除加法、包含min函式的棧

 一、構建乘積陣列: 1、題目: 給定一個數組A[0,1,...,n-1],請構建一個數組B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。 2、解題思路: B[i]的

面試題65:不用乘除加法

/*  * 面試題65:不用加減乘除做加法  * 題目:寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。  * 思路:首先看十進位制是如何做的: 5+7=12,三步走  * 第一步:相加各位的值,不算進位,得到2。  * 第二步:計算

劍指offer----不用乘除加法

題目描述 寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。 //拿101和111舉例說明 //n1為1010,即只標記了進位之後為1的位置,即101和111的最高為都為1, //即從右向左第三位都為1,則進位到第四位,則進位標記的第