Java 如何检查零是正还是负?

Java 如何检查零是正还是负?,java,floating-point,zero,Java,Floating Point,Zero,是否可以检查浮动是正零(0.0)还是负零(-0.0) 我已经将浮点数转换为字符串,并检查第一个字符是否为'-',但还有其他方法吗?是,除以它1/+0.0f是+Infinity,但1/-0.0f是-Infinity。通过简单的比较,很容易找到哪一个,因此您可以得到: if (1 / x > 0) // +0 here else // -0 here (这假设x只能是两个零中的一个)您可以使用Float.floatToIntBits将其转换为int,并查看位模式: float

是否可以检查浮动是正零(0.0)还是负零(-0.0)


我已经将
浮点数
转换为
字符串
,并检查第一个
字符
是否为
'-'
,但还有其他方法吗?

是,除以它
1/+0.0f
+Infinity
,但
1/-0.0f
-Infinity
。通过简单的比较,很容易找到哪一个,因此您可以得到:

if (1 / x > 0)
    // +0 here
else
    // -0 here

(这假设
x
只能是两个零中的一个)

您可以使用
Float.floatToIntBits
将其转换为
int
,并查看位模式:

float f = -0.0f;

if (Float.floatToIntBits(f) == 0x80000000) {
    System.out.println("Negative zero");
}

绝对不是最好的办法。签出函数

Float.floatToRawIntBits(f);
Doku:

/**
*返回指定浮点值的表示形式
*根据IEEE 754浮点“单格式”位
*布局,保留非数字(NaN)值。
*
*位31(掩码选择的位
*{@code 0x8000000})表示浮点的符号
*号码。
...
公共静态本机int floatorawintbits(浮点值);

Math.min所使用的方法与Jesper所提出的方法相似,但更为清晰:

private static int negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);

float f = -0.0f;
boolean isNegativeZero = (Float.floatToRawIntBits(f) == negativeZeroFloatBits);
当浮点为负时(包括
-0.0
-inf
),它使用与负整数相同的符号位。这意味着您可以将整数表示与
0
进行比较,无需知道或计算
-0.0
的整数表示:

if(f == 0.0) {
  if(Float.floatToIntBits(f) < 0) {
    //negative zero
  } else {
    //positive zero
  }
}
在Java中区分±0.0。(还有一个。)

我有点惊讶没有人提到这些,因为在我看来,它们比目前给出的任何方法都要清晰

对于负片:

new Double(-0.0).equals(new Double(value));
对于正面:

new Double(0.0).equals(new Double(value));

检查符号位(最左边的位)应该是足够的。实际上,零既不是负数,也不是正数。@GrijeshChauhan:仅限theoretically@fridge当前位置问题不是关于数学,而是关于Java。浮点值可能与数字有关的任何关系都是人为设计的,并且容易产生漏洞百出的抽象;-)这可能是一个愚蠢的问题,但我只是想知道:为什么需要区分正负0?用Math.copySign将零的符号转换为不同的数字,比如1.0,不是更容易吗?例如,
if(math.copySign(1.0,x)<0.0).
@njuffa:不确定如何
math.copySign(1.0,x)0
。我的意思是这两个都是不可解释的,所以你想要一个函数来实现它anyway@njuffa:是的,我认为您的答案存在可读性问题;)我没有考虑除法会很重,因为可能有一个特殊的情况为零除法无论如何,如果你们想进入它是多么重…视情况而定。例如,使用x87指令进行符号传输很烦人,但使用SSE很好。对于除法所需的时间,范围从9(我想?)到100多个周期(取决于被除法的值和µ拱)。任何一个都可能赢,这只是在x86系统上。如果你只是想提高效率,那么将其转换为int并询问符号位不是最好的解决方案吗?我不确定在Java中这样做的效率有多高,但在大多数体系结构中,这可以简单地通过OR指令后跟跳转零或跳转非零指令来实现,而OR通常是单周期的。不过,有条件的跳转成本因架构而异;但是,您可能不希望仅为了比较两个值而在堆上分配两个对象。这比除法要好得多,除法可能需要几个时钟周期,并且可能会在FPU单元中捕获溢出情况。更好的是:
(Float.floatToIntBits(f)&0x8000000)<0
new Double(-0.0).equals(new Double(value));
new Double(0.0).equals(new Double(value));