Wie überprüfe ich, ob eine Null positiv oder negativ ist?

Lesezeit: 4 Minuten

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?

  • 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

Ja, durch sie teilen. 1 / +0.0f ist +Infinityaber 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 0wodurch 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
}

Benutzer-Avatar
Tridib

Zum Negativ:

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

Zum Positiven:

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

1217010cookie-checkWie überprüfe ich, ob eine Null positiv oder negativ ist?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy