2012-10-04 68 views
0

我的代碼在下面,它適用於大多數輸入,但我注意到,對於非常大的數字(2147483647除以2作爲特定示例),我得到分段錯誤並且程序停止工作。請注意,badd()和bsub()函數分別僅添加或減去整數。爲什麼我的按位分割函數會產生分段錯誤?

unsigned int bdiv(unsigned int dividend, unsigned int divisor){ 
    int quotient = 1; 
    if (divisor == dividend) 
    { 
     return 1; 
    } 
    else if (dividend < divisor) 
    { return -1; }// this represents dividing by zero 

    quotient = badd(quotient, bdiv(bsub(dividend, divisor), divisor)); 

    return quotient; 
} 

我對我的bmult()函數也有點麻煩。它適用於某些值,但程序失敗的值爲-8192倍3.此功能也列出。預先感謝您的幫助。對此,我真的非常感激!

int bmult(int x,int y){ 
    int total=0; 
    /*for (i = 31; i >= 0; i--) 
    { 
     total = total << 1; 
     if(y&1 ==1) 
     total = badd(total,x); 
    } 
    return total;*/ 
    while (x != 0) 
    { 
     if ((x&1) != 0) 
     { 
      total = badd(total, y); 
     } 
     y <<= 1; 
     x >>= 1; 
    } 
    return total; 
} 
+1

不是說我不知道​​猜測它們是什麼,在你的代碼中缺少兩個可能很重要的函數。你可能也想把它們帶進去。 – WhozCraig

+2

告訴我們你在哪裏得到segfault可能也很有用。 –

+0

就像我說過的那樣,bsub()和badd()函數只是簡單地加上或減去兩個整數,當輸入我在描述中列出的值時發生故障。前兩個函數起作用,所以我不想通過爲他們顯示代碼來更長時間地提出問題。 – LulzCow

回答

1

您的bdiv問題很可能是由遞歸深度引起的。在你給出的例子中,你將把大約1073741824幀放到堆棧上,基本上使用了你分配的內存。

實際上,這個函數不需要遞歸。我可以很容易地轉換爲迭代解決方案,緩解堆棧問題。

+0

我試圖用一個while循環來增加1到商數,只要dividend> divisor和每次迭代從dividend減去除數,但是當我將一些非常大的數字除以2時,我最終得到一個無限循環。爲什麼可以這樣是? – LulzCow

+0

無限還是真的很長? – jpm

1

在乘法,這條線將要溢出和截斷y,所以badd()將越來越輸入錯誤:

y<<=1; 

這條線:

x>>=1; 

不會爲工作負x好。大多數編譯器會在這裏做一個所謂的算術移位,就像一個正常的移位,0移到最高位,但是有一個轉折,最重要的位不會改變。所以,將任何負值轉移到最終會給你-1。 -1右移將保持-1,導致乘法中的無限循環。

您不應該使用該算法來乘法無符號整數來乘以有符號整數。如果它在覈心中使用簽名類型,它不太可能工作得很好(如果有的話)。

如果您想要乘上有符號整數,您可以首先使用無符號類型實現無符號整數的乘法運算。然後你可以使用它來進行有符號乘法運算。這幾乎適用於所有系統,因爲它們使用有符號整數的2的補碼錶示。

實例(假定16位2的補碼整數):

-1 * 1 - >爲0xFFFF * 1 = 0xFFFF的 - >轉換回簽署 - > -1
-1 * -1 - >爲0xFFFF *爲0xFFFF = 0xFFFE0001 - >截斷爲16位&轉換爲帶符號 - > 1

在劃分以下兩行

else if (dividend < divisor) 
{ return -1; }// this represents dividing by zero 

是完全錯誤的。想想,1/2是多少?它是0,不是-1或(unsigned int)-1。

此外,多少錢是UINT_MAX/1?它是UINT_MAX。因此,當您的分工函數返回UINT_MAX(unsigned int)-1時,您將無法辨別差異,因爲這兩個值是相同的。你真的應該使用不同的機制來通知調用者溢出。

哦,當然,這條線:

quotient = badd(quotient, bdiv(bsub(dividend, divisor), divisor)); 

將會導致堆棧溢出,當該商預期爲大。不要遞歸執行此操作。至少,請使用循環代替。

相關問題