判断一个数是偶数还是奇数的最快方法是什么?
判断一个数是偶数还是奇数的最快方法是什么?
What is the fastest way to find if a number is even or odd?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
判断一个数是偶数还是奇数的最快方法是什么?
What is the fastest way to find if a number is even or odd?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(12)
众所周知,它
比
is_odd_A
更高效,但是在优化器打开的情况下,
is_odd_B
与is_odd_A
没有什么不同吗?否 — 使用gcc-4.2 -O2
,我们得到(在 ARM 汇编中):我们看到
is_odd_B
比is_odd_A
多需要 3 条指令,主要原因是因为但是,以下所有版本都会生成与
is_odd_A
相同的代码:这是什么意思?优化器通常足够复杂,对于这些简单的东西,最清晰的代码足以保证最佳效率。
It is pretty well known that
is more efficient than
But with the optimizer on, will
is_odd_B
be no different fromis_odd_A
? No — withgcc-4.2 -O2
, we get, (in ARM assembly):We see that
is_odd_B
takes 3 more instructions thanis_odd_A
, the main reason is becauseHowever, all the following versions will generate the same code as
is_odd_A
:What does this mean? The optimizer is usually sophisticated enough that, for these simple stuff, the clearest code is enough to guarantee best efficiency.
通常的方法:
替代方案:
在 GCC 3.3.1 和 4.3.2 上进行测试,两者的速度大致相同(没有编译器优化),因为两者都会产生
和
指令(在 x86 上编译) -我知道使用div
指令进行取模会慢很多,因此我根本没有测试它。Usual way to do it:
Alternative:
Tested on GCC 3.3.1 and 4.3.2, both have about the same speed (without compiler optimization) as both result in the
and
instruction (compiled on x86) - I know that using thediv
instruction for modulo would be much slower, thus I didn't test it at all.如果 (x & 1) 为真,则为奇数,否则为偶数。
if (x & 1) is true then it's odd, otherwise it's even.
哦等等,你说的是最快方式,而不是最有趣。我的错;)
当然,上述函数仅适用于正数。
Oh wait, you said fastest way, not funniest. My bad ;)
Above function only works for positive numbers of course.
检查最后一位是否为 1。
Check to see if the last bit is 1.
你的问题没有完全具体化。无论如何,答案取决于您的编译器和机器的体系结构。例如,您使用的计算机是否使用补码或二进制补码有符号数字表示形式?
我编写的代码首先是正确的,其次是清晰的,第三是简洁的,最后是快速的。因此,我将这个例程编码如下:
这个方法是正确的,它比测试 LSB 更清楚地表达了意图,它很简洁,不管你相信与否,它的速度非常快。当且仅当分析告诉我这种方法是我的应用程序中的瓶颈时,我才会考虑偏离它。
Your question is not completely specified. Regardless, the answer is dependent on your compiler and the architecture of your machine. For example, are you on a machine using one's complement or two's complement signed number representations?
I write my code to be correct first, clear second, concise third and fast last. Therefore, I would code this routine as follows:
This method is correct, it more clearly expresses the intent than testing the LSB, it's concise and, believe it or not, it is blazing fast. If and only if profiling told me that this method were a bottleneck in my application would I consider deviating from it.
如果它是一个整数,可能只检查最低有效位。零将被视为偶数。
If it's an integer, probably by just checking the least significant bit. Zero would be counted as even though.
可移植方法是使用模运算符
%
:如果您知道您只会在二进制补码架构上运行,那么您可以使用按位与:
相对于按位与,使用模运算符可能会导致代码变慢;但是,除非满足以下所有条件,否则我会坚持使用它:
x % 2
很多(比如在一个被执行数千次的紧密循环中);The portable way is to use the modulus operator
%
:If you know that you're only ever going to run on two's complement architectures, you can use a bitwise and:
Using the modulus operator can result in slower code relative to the bitwise and; however, I'd stick with it unless all of the following are true:
x % 2
a lot (say in a tight loop that's being executed thousands of times);检查最低有效位:
Check the least significant bit:
如果输入以 10 为基数,您不能只查看最后一位数字并检查它是偶数还是奇数吗?
{1, 3, 5, 7, 9}
为奇数{0, 2, 4, 6, 8}
为偶数其他信息: OP 指出一个数字是给定的,所以我在构建这个答案时遵循了这一点。这还要求数字以 10 为基数。根据以 10 为基数的偶数/奇数定义,该答案在数学上是正确的。根据用例,只需检查最后一位数字即可获得数学上一致的结果。
注意:如果您的输入已经是
int
,则只需检查其低位即可。这个答案仅对表示为数字序列的数字有用。您可以转换int->string来执行此操作,但这会比n % 2 == 0
慢得多。检查最后一位数字确实适用于任何偶数基数的数字字符串,而不仅仅是 10。对于低于 10 的基数,例如基数 8(八进制),9 和 8 不是可能的数字,但低位数字是奇数或偶数仍然判断是否是整数。
对于高于 10 的基数,会有额外的可能性,但无论如何您都不想搜索列表,只需使用正常的
i % 2 == 0
i % 2 == 0检查作为整数的数字是奇数还是偶数code> 或!=0
检查。对于使用
'a'
..'f'
表示数字值 10 到 15 的 ASCII 十六进制,ASCII 代码的低位不表示奇数或偶数,因为'a' == 0x61
(奇数)但代表10
又名0xa
(偶数)。因此,您必须将十六进制数字转换为整数,或者对 ASCII 代码进行一些位修改,以根据其他位或条件翻转低位。Can't you just look at the last digit and check if its even or odd if the input is in base 10?
{1, 3, 5, 7, 9}
is odd{0, 2, 4, 6, 8}
is evenAdditional info: The OP states that a number is a given, so I went with that when constructing this answer. This also requires the number to be in base 10. This answer is mathematically correct by definition of even/odd in base 10. Depending on the use case, you have a mathematically consistent result just by checking the last digit.
Note: If your input is already an
int
, just check the low bit of that. This answer is only useful for numbers represented as a sequence of digits. You could convert int->string to do this, but that would be much slower thann % 2 == 0
.Checking the last digit does work for a string of digits in any even base, not just 10. For bases lower than 10, like base 8 (octal), 9 and 8 aren't possible digits, but the low digit being odd or even still determines whether the whole number is.
For bases higher than 10, there will be extra possibilities, but you don't want to search a list anyway, just check if the digit as an integer is odd or even using the normal
i % 2 == 0
or!=0
check.For ASCII hex using
'a'
..'f'
to represent digits values 10 through 15, the low bit of ASCII code does not represent odd or even, because'a' == 0x61
(odd) but represents10
aka0xa
(even). So you'd have to convert the hex digit to an integer, or do some bit-hack on the ASCII code to flip the low bit according to some other bit or condition.