【问题标题】:How to differentiate between two integers without equality operators?如何区分没有相等运算符的两个整数?
【发布时间】:2012-09-08 17:05:17
【问题描述】:

给定两个整数,如何在不使用 if 语句或选择(>=、> 和 =)的情况下区分这两个整数、最大值、最小值和相等性。我考虑过使用fminfmax,但我还需要知道如何知道这两个整数是否相同。

【问题讨论】:

  • 这是作业吗?如果是这样标记它。
  • 您还应该知道,在 SO 上发布家庭作业问题有些可疑。你不是在寻求帮助,而是在寻求答案。如果你的教授发现了这一点,你很可能会被大学开除(我们在 我的大学这样做!)
  • 如果你不能使用>,你很可能也不能使用fmax :)
  • 作业标签已过时,不应使用。见stackoverflow.com/tags/homework/info
  • @AnalogFile 在我尝试这样标记它时看到了这一点..

标签: c integer max min


【解决方案1】:

假设 2 的补码算法:

int intcmp(int int1, int int2)
{
    int diff=int2-int1;
    unsigned int udiff;
    memcpy(&udiff, &diff, sizeof(diff));
    if(!udiff)
        return 0;  /* the two integers are equal */
    else if(udiff & 1<<(sizeof(udiff)*CHAR_BIT-1))  /* check the sign */
        return +1;  /* int1 < int2 */
    else
        return -1;  /* int2 < int1 */
}

【讨论】:

  • 因为我从不觉得用有符号整数做按位处理(尤其是 操作符号位)是安全的,所以每次我检查标准时,都会有一个新的 UB 准备好命中。所以我更喜欢安全起见,将结果复制到unsigned int“原始方式”以确保安全。它可能更冗长,但至少我不会被语言层挑剔,也不会被过度热心的优化器咬伤。
  • 你(OP)应该知道我的答案和@MatteoItalia 的答案将编译成几乎完全相同相同的代码:-)
  • @KristopherMicinski:我很确定这对于 INT_MAX/INT_MIN 组合也失败了,像你一样进入 UB 进行减法。
【解决方案2】:

怎么样...

(num1-num2) ? ((num1-num2) & (MAX_INT+1) ? NEGATIVE : POSITIVE) : EQUAL

【讨论】:

  • 查看三元运算符 ?: 的工作原理。 (测试) ?甲:乙。如果 test 为真,则评估 a,如果为 false,则评估 b。在这种情况下,如果 num1-num2 为零,那么什么是真的?使用相同的推理来找出内壳。
  • 这是一个很好的观点,你是绝对正确的。我写这个是因为它比你的快,但为了避免 UB,我会坚持使用你的。
  • 我很确定任何像样的编译器,正如你所说,无论如何都会生成相同的代码...... :)
  • 无论如何 num1 == INT_MAX 和 num2 == INT_MIN 都会失败。
  • 只要能做常量折叠,就可以。
【解决方案3】:

“区分”是什么意思?如果没有某种分支操作,你不能让两个数字选择两个不同的执行路径,但理论上你可以加载一个带有函数指针的数组并操纵数字来选择不同的数组元素来调用(调用是一种形式分支)。

您可以更轻松地加载具有两个不同字符串指针的数组,并根据您获得的数字选择要打印的数组。

您可以通过与 1 进行与运算来将一个数字转换为 0 或 1,具体取决于它是奇数还是偶数,例如。您可以通过减去它们并查看是否为零来确定数字是否相等。等等。

【讨论】:

    【解决方案4】:

    您可以使用以下内容生成掩码

    signed int x = ...;
    signed int y = ...;
    mask = (x - y) >> 31;
    

    所以如果 y>x,mask-1,否则是 0(但要小心溢出)。然后,您可以使用 &amp;|~ 使用此掩码构建您的结果。

    【讨论】:

      猜你喜欢
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-22
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多