C 整数均匀度测试(%2 vs&;1)

C 整数均匀度测试(%2 vs&;1),c,C,这两条语句是否等效编译:n%2==0和n&1==0 如果不是的话,是不是一个更有效?它们不会等价地编译。(事实上,我应该说这取决于编译器。但更安全的假设是,编译将是不同的)。 (n&1)是有效的。(同样。不确定endian的内容,我会检查并让您知道。) 好的-检查了endian的东西。它与字节的顺序有关,而与位的顺序无关。因此(n&1)必须是独立于平台的 这取决于您的编译器 x86体系结构上的优化编译器可能会将n%2转换为n&1,因为它们对于2s补码整数是等效的。同一平台上的不同编译器,或不同平

这两条语句是否等效编译:n%2==0和n&1==0


如果不是的话,是不是一个更有效?

它们不会等价地编译。(事实上,我应该说这取决于编译器。但更安全的假设是,编译将是不同的)。
(n&1)是有效的。(同样。不确定endian的内容,我会检查并让您知道。)

好的-检查了endian的东西。它与字节的顺序有关,而与位的顺序无关。因此(n&1)必须是独立于平台的

这取决于您的编译器

x86体系结构上的优化编译器可能会将
n%2
转换为
n&1
,因为它们对于2s补码整数是等效的。同一平台上的不同编译器,或不同平台上的相同编译器,可能会给出其他结果

我的建议是使用
n%2
,因为这是您试图用数学术语完成的,并在开始微优化之前对您的应用程序进行分析。

A昨天被问到

i%2
i&1
不一样:

  • 如果整数不是无符号的,根据其表示形式,
    n&1
    不一定表示整数是偶数还是奇数
  • i%2
    可以为负数

对于无符号整数,一个好的编译器应该合理地生成同样有效的代码。

无论哪一个更快,而且这也不太可能有什么关系,
n%2==0
是首选的,因为它清楚地表明了您的意图。更喜欢的原因是你喜欢写代码> *2 < /COD>到位移位。

< P>我曾经在C++中写过一个任意的精确整数库。%和&都被重载了,以至于它们在非常大的整数上实现了您所期望的效果。任意精度模非常复杂,而任意精度位测试则不复杂。由于这种洞察力,我总是喜欢(n&1),因为我知道幕后发生了什么。当然,您可以说智能编译器可能会将(n%2)优化为与(n&1)相同的指令集,但您真正的意思是“我使用%是错误的,希望我的编译器比我更智能。”忽略(n%2)更容易理解的注释。事实证明(n&1)也很容易理解(嗯,也许对我祖母来说不是)。使用&,这是正确的方法。

不,它们并不总是给出相同的结果。C标准允许一个人的补码实现,在这种情况下,他们将给出不同的结果,因为负数
n

不会进入它。不同的整数表示法可以-一个人的补码负数不是
(n&1)
,如果它们是不均匀的。@gnud:-谢谢,伙计。我花了些时间才弄明白这一点。:-)再加上智能编译器会找到这样简单的优化。@空格为true,但即使编译器无法找到优化,我仍然会使用更清晰的编码。请看:)这一点是我在回答和评论中试图提出的,但没有这里说得那么清楚:)如果我可以否定,请在使用前调用abs%2如果你想测试偶数,那么
i%2==0
对于负数是正确的
i
i&1对于两个补码的实现是正确的(这基本上就是所有的东西)。我想你总是写两次幂的乘法,并且有一个位偏移。哈哈,我们不要太过火了。在这种情况下,我几乎总是倍增,因为和你一样,我提倡明确的意图,而不是在通常不需要的地方进行微观优化。在这个特殊的例子中,(n&1)是用来测试(奇偶)性的正确习惯用法。它不仅更快,而且总是很清楚,因为你从来没有将构造用于其他任何东西(即,如果你将n视为标志字段,那么作为一个好的程序员,你将使用一个命名的位掩码常量而不是1)。太糟糕了,它不可移植。哈哈,不可移植到什么?每个现代操作系统都使用2的补码整数表示法和n&1来测试正整数和负整数的均匀性。如果你计划将一个端口连接到20世纪80年代某个单独的黑客硬件上,这些硬件只卖几台,那么你一定要担心可移植性。有一件事(n&1)是你的意图。您应该编写希望代码执行的操作,并依靠编译器正确处理它。这似乎是一种牺牲代码可维护性的低级过早优化。