Как проверить, является ли нуль положительным или отрицательным?

Можно ли проверить, является ли float положительным нулем (0.0) или отрицательным нулем (-0.0)?

Я преобразовал float в String и проверил, является ли первый char '-', но есть ли другие способы?

Ответы

Ответ 1

Да, разделите его. 1 / +0.0f - +Infinity, но 1 / -0.0f - -Infinity. Легко узнать, какой из них он представляет с простым сравнением, поэтому вы получаете:

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

(это предполагает, что x может быть только одним из двух нулей)

Ответ 2

Вы можете использовать Float.floatToIntBits, чтобы преобразовать его в int и посмотреть на шаблон бита:

float f = -0.0f;

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

Ответ 3

Определенно не лучший aproach. Оформить функцию

Float.floatToRawIntBits(f);

Доку:

/**
 * Returns a representation of the specified floating-point value
 * according to the IEEE 754 floating-point "single format" bit
 * layout, preserving Not-a-Number (NaN) values.
 *
 * <p>Bit 31 (the bit that is selected by the mask
 * {@code 0x80000000}) represents the sign of the floating-point
 * number.
 ...
 public static native int floatToRawIntBits(float value);

Ответ 4

Подход, используемый Math.min, аналогичен тому, что предлагает Jesper, но немного яснее:

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

float f = -0.0f;
boolean isNegativeZero = (Float.floatToRawIntBits(f) == negativeZeroFloatBits);

Ответ 5

Double.equals выделяет ± 0.0 на Java. (Там также Float.equals.)

Я немного удивлен, что никто не упомянул об этом, поскольку они кажутся мне более ясными, чем любой метод, данный до сих пор!

Ответ 6

Когда float отрицательный (включая -0.0 и -inf), он использует тот же самый знаковый бит, что и отрицательный int. Это означает, что вы можете сравнить целочисленное представление с 0, исключая необходимость знать или вычислять целочисленное представление -0.0:

if(f == 0.0) {
  if(Float.floatToIntBits(f) < 0) {
    //negative zero
  } else {
    //positive zero
  }
}

У этого есть дополнительная ветвь над принятым ответом, но я думаю, что это более читаемо без шестнадцатеричной константы.

Если ваша цель состоит в том, чтобы лечить -0 как отрицательное число, вы можете оставить вне инструкции if:

if(Float.floatToIntBits(f) < 0) {
  //any negative float, including -0.0 and -inf
} else {
  //any non-negative float, including +0.0, +inf, and NaN
}

Ответ 7

В ES6 вы можете использовать Object.is(). Это немного более подробный, но также более четкий и надежный, чем верхний ответ (1/x < 0).

Object.is(-0,-0);  // true
Object.is(0,-0);   // false

Ответ 8

Не уверен в Java, но на других языках, например C/С++, наиболее подходящий способ:

inline bool IsNegativeZero(float fl)
{
    return (fl & 0x80000000);
}

inline bool IsPozitiveZero(float fl)
{
    return (fl & 0x00000000);
}

Этот способ работает, поскольку IEEE-754 описывает, что MSB (самый старший бит) числа с плавающей запятой определяет, является ли он положительным или отрицательным, другие биты указывают значение.


Я называю это наиболее подходящим, потому что для его проверки требуются минимальные циклы CPU.

Ответ 9

Для отрицательных:

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

Для положительных:

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