Можно ли проверить, является ли float
положительным нулем (0.0) или отрицательным нулем (-0.0)?
Я преобразовал float
в String
и проверил, является ли первый char
'-'
, но есть ли другие способы?
Можно ли проверить, является ли float
положительным нулем (0.0) или отрицательным нулем (-0.0)?
Я преобразовал float
в String
и проверил, является ли первый char
'-'
, но есть ли другие способы?
Да, разделите его. 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");
}
Определенно не лучший 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);
Подход, используемый Math.min
, аналогичен тому, что предлагает Jesper, но немного яснее:
private static int negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
float f = -0.0f;
boolean isNegativeZero = (Float.floatToRawIntBits(f) == negativeZeroFloatBits);
Double.equals
выделяет ± 0.0 на Java. (Там также Float.equals
.)
Я немного удивлен, что никто не упомянул об этом, поскольку они кажутся мне более ясными, чем любой метод, данный до сих пор!
Когда 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
}
В ES6 вы можете использовать Object.is(). Это немного более подробный, но также более четкий и надежный, чем верхний ответ (1/x < 0)
.
Object.is(-0,-0); // true
Object.is(0,-0); // false
Не уверен в Java, но на других языках, например C/С++, наиболее подходящий способ:
inline bool IsNegativeZero(float fl)
{
return (fl & 0x80000000);
}
inline bool IsPozitiveZero(float fl)
{
return (fl & 0x00000000);
}
Этот способ работает, поскольку IEEE-754 описывает, что MSB (самый старший бит) числа с плавающей запятой определяет, является ли он положительным или отрицательным, другие биты указывают значение.
Я называю это наиболее подходящим, потому что для его проверки требуются минимальные циклы CPU.
Для отрицательных:
new Double(-0.0).equals(new Double(value));
Для положительных:
new Double(0.0).equals(new Double(value));
Object.is(0, -0);//false Object.is(-0, -0);//true