检查两个整数是否具有相同符号的最简单方法?
检查两个整数是否具有相同符号的最简单方法是什么? 有没有什么简短的按位技巧可以做到这一点?
Which is the simplest way to check if two integers have same sign? Is there any short bitwise trick to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
如果(x*y)> 0...
假设非零等等。
if (x * y) > 0...
assuming non-zero and such.
假设二进制补码算术(http://en.wikipedia.org/wiki/Two_complement):
在经过优化的现代处理器上,这只需两条指令,耗时不到 1 纳秒。
不假设二进制补码算术:
这可能需要一两个额外的指令并且需要更长的时间。
使用乘法是一个坏主意,因为它容易溢出。
Assuming twos complement arithmetic (http://en.wikipedia.org/wiki/Two_complement):
This can take as little as two instructions and less than 1ns on a modern processor with optimization.
Not assuming twos complement arithmetic:
This may require one or two extra instructions and take a little longer.
Using multiplication is a bad idea because it is vulnerable to overflow.
(整数1 * 整数2)> 0
因为当两个整数共用一个符号时,相乘的结果将始终为正。
如果您无论如何都想将 0 视为相同的符号,也可以使其 >= 0。
(integer1 * integer2) > 0
Because when two integers share a sign, the result of multiplication will always be positive.
You can also make it >= 0 if you want to treat 0 as being the same sign no matter what.
假设 32 位整数:
稍微简洁一些:
Assuming 32 bit ints:
Slightly more terse:
我不太确定我是否会将“按位技巧”和“最简单”视为同义词。 我看到很多答案都假设有符号 32 位整数(尽管要求无符号会很愚蠢); 我不确定它们是否适用于浮点值。
似乎“最简单”的检查是比较两个值与 0 的比较; 假设可以比较类型,这是非常通用的:
如果符号相反,则结果为 false。 如果迹象相同,则说明正确。
I'm not really sure I'd consider "bitwise trick" and "simplest" to be synonymous. I see a lot of answers that are assuming signed 32-bit integers (though it would be silly to ask for unsigned); I'm not certain they'd apply to floating-point values.
It seems like the "simplest" check would be to compare how both values compare to 0; this is pretty generic assuming the types can be compared:
If the signs are opposite, you get false. If the signs are the same, you get true.
使用 std::signbit 的更好方法如下:
它还支持其他基本类型(
double
、float
、char
等)。Better way using std::signbit as follows:
It also support other basic types (
double
,float
,char
etc).作为技术说明,即使在现代架构上,位运算解决方案也将比乘法高效得多。 您只节省了大约 3 个周期,但您知道他们所说的“节省一分钱”......
As a technical note, bit-twiddly solutions are going to be much more efficient than multiplication, even on modern architectures. It's only about 3 cycles that you're saving, but you know what they say about a "penny saved"...
就在我头顶上...
Just off the top of my head...
if (a*b < 0) 符号不同,否则符号相同(或 a 或 b 为零)
if (a*b < 0) sign is different, else sign is the same (or a or b is zero)
无分支 C 版本:
整数类型的 C++ 模板:
branchless C version:
C++ template for integer types:
对于任意大小的 int 进行二进制补码算术:
For any size of int with two's complement arithmetic:
假设 32 位
if(((x^y) & 0x80000000) == 0)
...答案
if(x*y>0)
不好,因为溢出assuming 32 bit
if(((x^y) & 0x80000000) == 0)
... the answer
if(x*y>0)
is bad due to overflow回想一下我的大学时代,在大多数机器表示中,整数的最左边的位不就是负数时为 1,正数时为 0 吗?
不过,我想这相当依赖于机器。
Thinking back to my university days, in most machine representations, isn't the left-most bit of a integer a 1 when the number is negative, and 0 when it's positive?
I imagine this is rather machine-dependent, though.
int same_sign = !( (x >> 31) ^ (y >> 31) );
如果(相同的符号)...
别的 ...
int same_sign = !( (x >> 31) ^ (y >> 31) );
if ( same_sign ) ...
else ...
这是一个在 C/C++ 中工作的版本,不依赖于整数大小或存在溢出问题(即 x*y>=0 不起作用)
当然,您可以 geek out 和模板:
注意:因为我们使用异或,当符号相同时,我们希望 LHS 和 RHS 不同,因此对零进行不同的检查。
Here is a version that works in C/C++ that doesn't rely on integer sizes or have the overflow problem (i.e. x*y>=0 doesn't work)
Of course, you can geek out and template:
Note: Since we are using exclusive or, we want the LHS and the RHS to be different when the signs are the same, thus the different check against zero.
有什么问题吗
?
What's wrong with
?
我会对任何确定整数符号的按位技巧保持警惕,因为这样你就必须假设这些数字在内部如何表示。
几乎 100% 的情况下,整数都会存储为二的补码,但这不是一个好习惯除非您使用保证特定存储格式的数据类型,否则请对系统的内部结构做出假设。
在二进制补码中,您只需检查整数中的最后(最左边)位即可确定它是否为负数,因此您可以仅比较这两个位。 这意味着 0 与正数具有相同的符号,这与大多数语言中实现的符号函数不一致。
就我个人而言,我只会使用您选择的语言的符号功能。 像这样的计算不太可能出现任何性能问题。
I would be wary of any bitwise tricks to determine the sign of integers, as then you have to make assumptions about how those numbers are represented internally.
Almost 100% of the time, integers will be stored as two's compliment, but it's not good practice to make assumptions about the internals of a system unless you are using a datatype that guarentees a particular storage format.
In two's compliment, you can just check the last (left-most) bit in the integer to determine if it is negative, so you can compare just these two bits. This would mean that 0 would have the same sign as a positive number though, which is at odds with the sign function implemented in most languages.
Personally, I'd just use the sign function of your chosen language. It is unlikely that there would be any performance issues with a calculation such as this.
如果符号相同,则计算结果为 1,否则计算结果为 0。
will evaluate to 1 if the sign is the same, 0 otherwise.