Kann man prüfen, ob a float
ist eine positive Null (0,0) oder eine negative Null (-0,0)?
Ich habe die konvertiert float
zu einem String
und überprüft, ob die erste char
ist ein '-'
aber gibt es noch andere Möglichkeiten?
Kann man prüfen, ob a float
ist eine positive Null (0,0) oder eine negative Null (-0,0)?
Ich habe die konvertiert float
zu einem String
und überprüft, ob die erste char
ist ein '-'
aber gibt es noch andere Möglichkeiten?
Ja, durch sie teilen. 1 / +0.0f
ist +Infinity
aber 1 / -0.0f
ist -Infinity
. Mit einem einfachen Vergleich lässt sich leicht herausfinden, um welches es sich handelt. So erhalten Sie:
if (1 / x > 0)
// +0 here
else
// -0 here
(das setzt voraus x
kann nur eine der beiden Nullen sein)
Wäre es nicht einfacher, mit Math.copySign das Vorzeichen der Null auf eine andere Zahl, sagen wir 1,0, zu übertragen? Z.B if (math.copySign (1.0, x) < 0.0) ...
– njuffa
14. März 2014 um 17:39 Uhr
@njuffa: Nicht sicher wie math.copySign(1.0,x)<0.0
ist “einfacher” als 1/x>0
. Ich meine, beide sind ziemlich un-selbsterklärend, also willst du sowieso eine Funktion dafür haben
– Niklas B.
14. März 2014 um 20:06 Uhr
@njuffa: Ja, ich dachte, Sie hätten Probleme mit der Lesbarkeit dieser Antwort;) Ich dachte nicht, dass die Division schwer sein würde, da es wahrscheinlich sowieso einen Sonderfall für Nullteiler gibt
– Niklas B.
14. März 2014 um 21:39 Uhr
Nun, wenn ihr darauf eingehen wollt, wie schwer es ist, dann kommt es darauf an. Beispielsweise ist eine Zeichenübertragung mit x87-Anweisungen ärgerlich, mit SSE jedoch großartig. Und wie lange die Division dauert, reicht von 9 (glaube ich?) bis über hundert Zyklen (abhängig von den zu dividierenden Werten und dem µarch). Beide können gewinnen, und das gilt nur für x86-Systeme.
– Harald
14. März 2014 um 21:43 Uhr
Wenn Sie nur Effizienz wollen, wäre es nicht die beste Lösung, es in ein int zu konvertieren und das Vorzeichenbit abzufragen? Ich bin mir nicht sicher, wie effizient Sie das in Java tun können, aber auf den meisten Architekturen kann dies einfach mit einer ODER-Anweisung gefolgt von einer Sprung-Null- oder Sprung-Nicht-Null-Anweisung erfolgen, und das ODER ist normalerweise ein Zyklus. Die bedingten Sprungkosten variieren jedoch stark je nach Architektur.
– reirab
15. März 2014 um 5:10 Uhr
Sie können verwenden Float.floatToIntBits
um es in ein umzuwandeln int
und schau dir das Bitmuster an:
float f = -0.0f;
if (Float.floatToIntBits(f) == 0x80000000) {
System.out.println("Negative zero");
}
Viel besser als eine Division, die mehrere Taktzyklen dauern kann und einen Überlaufzustand in der FPU-Einheit abfangen kann. Noch besser: (Float.floatToIntBits(f) & 0x80000000) < 0
– Markus Hieronymus
6. September 2018 um 9:59 Uhr
Definitiv nicht der beste Ansatz. Überprüfen Sie die Funktion
Float.floatToRawIntBits(f);
Doku:
/**
* 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);
Double.equals
unterscheidet ±0,0 in Java. (Es gibt auch Float.equals
.)
Ich bin etwas überrascht, dass niemand diese erwähnt hat, da sie mir klarer erscheinen als jede bisher gegebene Methode!
Der Ansatz von Math.min
ist ähnlich wie Jesper vorschlägt, aber etwas klarer:
private static int negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
float f = -0.0f;
boolean isNegativeZero = (Float.floatToRawIntBits(f) == negativeZeroFloatBits);
Wenn ein Float negativ ist (inkl -0.0
und -inf
), verwendet es das gleiche Vorzeichenbit wie ein negativer int. Dies bedeutet, dass Sie die ganzzahlige Darstellung mit vergleichen können 0
wodurch die Notwendigkeit entfällt, die ganzzahlige Darstellung von zu kennen oder zu berechnen -0.0
:
if(f == 0.0) {
if(Float.floatToIntBits(f) < 0) {
//negative zero
} else {
//positive zero
}
}
Das hat einen zusätzlichen Zweig über der akzeptierten Antwort, aber ich denke, es ist ohne eine Hex-Konstante besser lesbar.
Wenn Ihr Ziel nur darin besteht, -0 als negative Zahl zu behandeln, können Sie die äußere Zahl weglassen if
Aussage:
if(Float.floatToIntBits(f) < 0) {
//any negative float, including -0.0 and -inf
} else {
//any non-negative float, including +0.0, +inf, and NaN
}
Tridib
Zum Negativ:
new Double(-0.0).equals(new Double(value));
Zum Positiven:
new Double(0.0).equals(new Double(value));
Das Überprüfen des Vorzeichenbits (Bit ganz links) sollte ausreichen
– eingepackt__l
14. März 2014 um 15:23 Uhr
Tatsächlich ist Null weder eine negative noch eine positive Zahl.
– Grijesh Chauhan
14. März 2014 um 18:24 Uhr
@GrijeshChauhan: Nur theoretisch
– Muhende Ente
14. März 2014 um 18:33 Uhr
@fridge: Aber die Frage bezieht sich nicht auf Mathematik, sondern auf Java. Jede Beziehung, die Gleitkommawerte zu Zahlen haben könnten, ist menschliches Design und anfällig für undichte Abstraktionen 😉
– Steve Jessop
15. März 2014 um 15:10 Uhr
Vielleicht eine dumme Frage, aber ich habe mich nur gefragt: Warum muss man zwischen einer positiven und einer negativen 0 unterscheiden?
– Sieg
29. März 2014 um 22:13 Uhr