【问题标题】:Function that checks for overflow in addition of unsigned ints除了无符号整数之外检查溢出的函数
【发布时间】:2021-04-05 20:45:46
【问题描述】:

我必须创建检查整数加法、减法和无符号整数加法中溢出的函数(仅使用! ~ | & ^ + >> <<)。我已经为有符号整数加法和减法找到了函数,但我不知道如何为无符号整数加法做一个。

我该怎么做呢?

这是我已完成的 2 个功能的代码:

int twosAddOk(int x, int y){
    int z=x+y;
    int a=x>>31;
    int b=y>>31;
    int c=z>>31;
    return !!(a^b)|(!(a^c)&!(b^c));
}

int twosSubtractOK(int x, int y){
    int z=x+~y+1;
    return !(((x^y & x^z))>>31);
}

【问题讨论】:

  • 请出示您目前的支票代码。
  • @Barmar 看起来会违反约束
  • @AndrewHenle 我不允许使用 if 语句,只能使用我提供的运算符
  • @ians 为什么要限制运营商?什么应用程序需要它?看起来这会混淆代码。
  • 您的代码使用了赋值运算符=,它不在允许的列表中。 (此评论的重点是您只使用这些运算符的限制是愚蠢的。)

标签: c


【解决方案1】:

您可以通过困难的方式计算 MSB 的结转:

int unsignedAddOk(unsigned int x, unsigned int y){

    unsigned int x0=(~(1U<<31))&x; // MSB of x cleared
    unsigned int y0=(~(1U<<31))&y; // MSB of y cleared
    int c=(x0+y0)>>31; // Carry-in of MSB
    int a=x>>31; // MSB of x
    int b=y>>31; // MSB of y
    return !((a&b)|(a&c)|(b&c));
}

【讨论】:

  • @chux-ReinstateMonica 谢谢。现在修好了吗?
  • @chux-ReinstateMonica 你是对的。那时它们实际上都是布尔值。
【解决方案2】:

也许是一个无需编码幻数 31 的解决方案

// Return 1 on overflow
int unsigned_add_overflow_test(unsigned a, unsigned b) {
  // Add all but the LSBits and then add 1 if both LSBits are 1
  // When overflow would occur with a + b, sum's MSBit is set.
  unsigned sum = (a >> 1) + (b >> 1) + (a&b&1);
  // Test MSBit set
  //                vvv--------- All bits set
  return !!(sum & ~(-1u >> 1));
  //               ^^^^^^^^^^ -- All bits set, except MSBit
  //              ^^^^^^^^^^^ -- MSBit set, rest are 0 
}

或作为单线

!!( ((a >> 1) + (b >> 1) + (a&b&1)) & ~(-1u >> 1)) )

【讨论】:

    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多