2012-10-04 49 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)); 

将会导致堆栈溢出,当该商预期为大。不要递归执行此操作。至少,请使用循环代替。

相关问题