代码之家  ›  专栏  ›  技术社区  ›  Rubens Farias

对于负整数返回零

  •  8
  • Rubens Farias  · 技术社区  · 15 年前

    一个朋友抛出了一些类似于以下C代码的代码:

    int i = ...;
    return i < 0 ? 0 : i;
    

    这让我想。对于负整数或当前正值,有什么“不同”的返回零的方法吗?更具体地说,如果可能的话,我正在寻找逐位运算。

    顺便说一句,我知道 Math.Max(0, i);

    5 回复  |  直到 15 年前
        1
  •  27
  •   Tim Sylvester    15 年前

    怎么了? Math.Max ?

    可以 在没有分支的情况下使用按位运算执行等效操作:

    r = x ^ ((x ^ y) & -(x < y)); // == max(x, y)
    

    如果用零替换,它会折叠为:

    r = (y & -(0 < y)); // == max(0, y)
    

    (来源: this list 是位技巧。)

    如果分支在你的平台上非常昂贵,我想这在一些内部循环中可能是值得的,但是它非常模糊,我不想在 极其 时间敏感功能。

        2
  •  4
  •   Aaron    15 年前

    怎么样:

    In=…

    返回I&~(I>>31);

        3
  •  4
  •   Rune FS    15 年前

    下面的代码可以做到这一点,代码读起来非常好,实际上不需要注释;)

    ((((0x80000000 & i) >> 31)^1) * 0xFFFFFFFF) & i
    

    然后又

    int temp = (0x80000000 & i); //get the most significant bit (1 for negative 0 for positive)
    temp = (temp>>31)^1; //more it to the least significant and not it (we now have 0 for negative numbers and one for positive)
    
    temp *= 0xFFFFFFFF; //get a lof of F's if it's positive or a lot of zeros if the number was negative
    
    temp = temp & i; //and the F's/zeros with the original number
    

    所有负数和所有正数的Voila 0保持不变

        4
  •  3
  •   Carl Smotricz    15 年前

    简短回答:不。

    位运算符做的事情非常不同,或者更确切地说是用于不同的问题。

    如果你知道整数的大小,你可以测试最高的(最重要的)位;如果是1,数字是负数,你可以这样做。但这比简单的“<”测试要多得多。

        5
  •  3
  •   Kai Huppmann    15 年前

    不是按位而是不同的:

    return (i + Math.abs(i))/2
    

    编辑:

    return (int)(i/2f + Math.abs(i)/2f)