检查两个整数是否具有相同符号的最简单方法?

发布于 2024-07-04 13:50:18 字数 53 浏览 10 评论 0原文

检查两个整数是否具有相同符号的最简单方法是什么? 有没有什么简短的按位技巧可以做到这一点?

Which is the simplest way to check if two integers have same sign? Is there any short bitwise trick to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

萌辣 2024-07-11 13:50:18

如果(x*y)> 0...

假设非零等等。

if (x * y) > 0...

assuming non-zero and such.

贩梦商人 2024-07-11 13:50:18

假设二进制补码算术(http://en.wikipedia.org/wiki/Two_complement):

inline bool same_sign(int x, int y) {
    return (x^y) >= 0;
}

在经过优化的现代处理器上,这只需两条指令,耗时不到 1 纳秒。

不假设二进制补码算术:

inline bool same_sign(int x, int y) {
    return (x<0) == (y<0);
}

这可能需要一两个额外的指令并且需要更长的时间。

使用乘法是一个坏主意,因为它容易溢出。

Assuming twos complement arithmetic (http://en.wikipedia.org/wiki/Two_complement):

inline bool same_sign(int x, int y) {
    return (x^y) >= 0;
}

This can take as little as two instructions and less than 1ns on a modern processor with optimization.

Not assuming twos complement arithmetic:

inline bool same_sign(int x, int y) {
    return (x<0) == (y<0);
}

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.

陌生 2024-07-11 13:50:18

(整数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.

海未深 2024-07-11 13:50:18

假设 32 位整数:

bool same = ((x ^ y) >> 31) != 1;

稍微简洁一些:

bool same = !((x ^ y) >> 31);

Assuming 32 bit ints:

bool same = ((x ^ y) >> 31) != 1;

Slightly more terse:

bool same = !((x ^ y) >> 31);
黎夕旧梦 2024-07-11 13:50:18

我不太确定我是否会将“按位技巧”和“最简单”视为同义词。 我看到很多答案都假设有符号 32 位整数(尽管要求无符号很愚蠢); 我不确定它们是否适用于浮点值。

似乎“最简单”的检查是比较两个值与 0 的比较; 假设可以比较类型,这是非常通用的:

bool compare(T left, T right)
{
    return (left < 0) == (right < 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:

bool compare(T left, T right)
{
    return (left < 0) == (right < 0);
}

If the signs are opposite, you get false. If the signs are the same, you get true.

入怼 2024-07-11 13:50:18

使用 std::signbit 的更好方法如下:

std::signbit(firstNumber) == std::signbit(secondNumber);

它还支持其他基本类型(doublefloatchar 等)。

Better way using std::signbit as follows:

std::signbit(firstNumber) == std::signbit(secondNumber);

It also support other basic types (double, float, char etc).

林空鹿饮溪 2024-07-11 13:50:18
#include<stdio.h>

int checksign(int a, int b)
{
 return (a ^ b); 
}

void  main()
{
    int a=-1, b = 0;

    if(checksign(a,b)<0)
    {
        printf("Integers have the opposite sign");
    }
    else
    {
        printf("Integers have the same sign");
    }
}
#include<stdio.h>

int checksign(int a, int b)
{
 return (a ^ b); 
}

void  main()
{
    int a=-1, b = 0;

    if(checksign(a,b)<0)
    {
        printf("Integers have the opposite sign");
    }
    else
    {
        printf("Integers have the same sign");
    }
}
丢了幸福的猪 2024-07-11 13:50:18

作为技术说明,即使在现代架构上,位运算解决方案也将比乘法高效得多。 您只节省了大约 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"...

好多鱼好多余 2024-07-11 13:50:18

就在我头顶上...

int mask = 1 << 31;
(a & mask) ^ (b & mask) < 0;

Just off the top of my head...

int mask = 1 << 31;
(a & mask) ^ (b & mask) < 0;
帅气尐潴 2024-07-11 13:50:18

if (a*b < 0) 符号不同,否则符号相同(或 a 或 b 为零)

if (a*b < 0) sign is different, else sign is the same (or a or b is zero)

陌路黄昏 2024-07-11 13:50:18

无分支 C 版本:

int sameSign(int a, int b) {
    return ~(a^b) & (1<<(sizeof(int)*8-1));
}

整数类型的 C++ 模板:

template <typename T> T sameSign(T a, T b) {
    return ~(a^b) & (1<<(sizeof(T)*8-1));
}

branchless C version:

int sameSign(int a, int b) {
    return ~(a^b) & (1<<(sizeof(int)*8-1));
}

C++ template for integer types:

template <typename T> T sameSign(T a, T b) {
    return ~(a^b) & (1<<(sizeof(T)*8-1));
}
白云不回头 2024-07-11 13:50:18

对于任意大小的 int 进行二进制补码算术:

#define SIGNBIT (~((unsigned int)-1 >> 1))
if ((x & SIGNBIT) == (y & SIGNBIT))
    // signs are the same

For any size of int with two's complement arithmetic:

#define SIGNBIT (~((unsigned int)-1 >> 1))
if ((x & SIGNBIT) == (y & SIGNBIT))
    // signs are the same
阳光的暖冬 2024-07-11 13:50:18

假设 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

滥情哥ㄟ 2024-07-11 13:50:18

回想一下我的大学时代,在大多数机器表示中,整数的最左边的位不就是负数时为 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.

尬尬 2024-07-11 13:50:18

int same_sign = !( (x >> 31) ^ (y >> 31) );

如果(相同的符号)...
别的 ...

int same_sign = !( (x >> 31) ^ (y >> 31) );

if ( same_sign ) ...
else ...

短暂陪伴 2024-07-11 13:50:18

这是一个在 C/C++ 中工作的版本,不依赖于整数大小或存在溢出问题(即 x*y>=0 不起作用)

bool SameSign(int x, int y)
{
    return (x >= 0) ^ (y < 0);
}

当然,您可以 geek out 和模板:

template <typename valueType>
bool SameSign(typename valueType x, typename valueType y)
{
    return (x >= 0) ^ (y < 0);
}

注意:因为我们使用异或,当符号相同时,我们希望 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)

bool SameSign(int x, int y)
{
    return (x >= 0) ^ (y < 0);
}

Of course, you can geek out and template:

template <typename valueType>
bool SameSign(typename valueType x, typename valueType y)
{
    return (x >= 0) ^ (y < 0);
}

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.

方圜几里 2024-07-11 13:50:18

有什么问题吗

return ((x<0) == (y<0));  

What's wrong with

return ((x<0) == (y<0));  

?

晚风撩人 2024-07-11 13:50:18

我会对任何确定整数符号的按位技巧保持警惕,因为这样你就必须假设这些数字在内部如何表示。

几乎 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.

茶底世界 2024-07-11 13:50:18
(a ^ b) >= 0

如果符号相同,则计算结果为 1,否则计算结果为 0。

(a ^ b) >= 0

will evaluate to 1 if the sign is the same, 0 otherwise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文