Java中

时间:2017-01-18 10:37:13

标签: java math primitive

对于 int Math.signum(double) Math.signum(float)的等效函数>或。我不想写像

这样的代码
  int sign = (int) Math.signum((double) intValue);

当有更好的选择时。

2 个答案:

答案 0 :(得分:8)

答案 1 :(得分:1)

仅仅是该实现细节的附录:

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;第一位是符号),则向右移动 signed 1100 >> 11110(- 2)。做一个除法,但要保持标志。

因此,如果我们移位31次,我们将丢弃数字的最后31位,将符号的位移到最低有效位置,并保留原始符号。或者简单地讲取31位,将其置于0位置并丢弃其他所有内容。

 0 00000 ..... 11111
 x --------------->0 // x is kept
        ignore

第二部分-x >>> 31 unsigned 移位,这意味着在我们移位时 not 不保留。

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

1100(-4),我们尝试将其移位一次:1100 >>> 1,因为未保留符号 ,所以我们将最高有效位为零并移动在右边,因此我们得到:0110(+6!)。

实际上,将32位图像带入图像中。 -4 == 1111...111100,然后向右移动:符号为零,其他所有元素都向右移动,因此:0111...11110Integer.MAX_VALUE - 1

System.out.println(-4 >>> 1);
System.out.println(Integer.MAX_VALUE - 1);

因此,x >>> 31部分会将符号位移到最低有效位置,将所有其他位置清零。无论您输入多少数字,都将始终获得10

1 00000 ..... 11111
x --------------->1 // x is "zeroed also"
       ignore

只需将-x添加到x >>> 31上,以便|可以正确满足我们所需的结果。