首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java中int或long的Math.signum(double)等价函数

在Java中int或long的Math.signum(double)等价函数
EN

Stack Overflow用户
提问于 2017-01-18 10:37:13
回答 2查看 2.1K关注 0票数 5

对于其他原语数字,如Math.signum(double)、int、或long,在Java中是否有对应的函数用于或。我不想写这样的代码

代码语言:javascript
运行
复制
  int sign = (int) Math.signum((double) intValue);

当有更好的选择的时候。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-18 10:41:18

票数 10
EN

Stack Overflow用户

发布于 2019-03-20 11:24:14

只是这方面的一些实施细节的增编:

代码语言:javascript
运行
复制
public static int signum(int i) {
    // HD, Section 2-7
    return (i >> 31) | (-i >>> 31);
}

Integer::signum说:如果数字是负数,我会给你-1,如果数字是零,则给出0,如果数字是正,则给出1。例如,通过一些嵌套的if/else,这是相当微不足道的。

相反,JDK使用的解决方案有点花哨。(x >> 31) | (-x >>> 31)。看起来很容易,对吧?第一部分:x >> 31是向右的有符号移位;它被称为签名,因为它在转换后保留符号。

假设我们生活在一个只有4位数的世界里(为了简单起见)。

我们有0100 (+4),一个移位0100 >> 1将使它成为0010 (+2)。现在,如果我们的数字是1100 (-4;第一个位是符号),则向右移动:1100 >> 11110 (-2)。做个除法,但保持标牌。

因此,如果我们移动31次,我们扔掉最后31位的数字,移动符号的位在最不重要的位置,并保留原来的符号。或者简单地说,拿出31位,把它放到0的位置,扔掉所有其他的东西。

代码语言:javascript
运行
复制
 0 00000 ..... 11111
 x --------------->0 // x is kept
        ignore

第二部分-x >>> 31是一个无符号移位,意思是当我们移动时,符号不被保留。

例如,0100 >>> 1 (+4)将给您0010 (+2)。到目前为止,没有什么与有符号的shift和上面的例子有什么不同。有趣的是,当数字为负数时:

1100 (-4),我们尝试将它移一次:1100 >>> 1,因为符号不被保留,所以我们在最有意义的位中放置零并向右移动,从而得到:0110 (+6!)。

在现实中,采取32位进入图片。-4 == 1111...111100,我们把它移到右边:符号是零,其他的东西都移到右边,例如:0111...11110Integer.MAX_VALUE - 1

代码语言:javascript
运行
复制
System.out.println(-4 >>> 1);
System.out.println(Integer.MAX_VALUE - 1);

因此,部分x >>> 31将把符号位移动到最不重要的位置,对其他所有东西进行归零。无论你给它的号码是多少,你都会得到10

代码语言:javascript
运行
复制
1 00000 ..... 11111
x --------------->1 // x is "zeroed also"
       ignore

-x添加到x >>> 31中只是为了使|能够正确地工作,以满足我们所需的结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41717118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档