2015-12-01 15 views
13

Ich habe zwei Gleitkommazahl a und b. Ich möchte prüfen, ob sie unterschiedliche Zeichen haben. Der einfache Weg ist zu sehenGibt es eine einfache Möglichkeit zu überprüfen, ob zwei Zahlen unterschiedliche Zeichen haben?

Aber die beiden Zahlen sind sehr klein und a * b könnte Unterlauf sein. Eine andere einfache Möglichkeit, es zu überprüfen?

Wer denkt, es ist eine doppelte Frage, bitte geben Sie mir eine Antwort, die genau die Bedingung a * b < 0 entspricht. Beachten Sie, dass das Vorzeichen von 0 in meiner Frage nicht definiert ist.

+4

C++ 11 hat [signbit] (http://en.cppreference.com/w/cpp/numeric/math/signbit). Also wird etwas "signbit (a) == signbit (b)" wahr sein, wenn beide das gleiche Vorzeichen haben. – wendelbsilva

+0

fwiw, vs2012 scheint nicht signbit zu haben. 2013 tut es jedoch. Kannst du nicht einfach eine Zahl mit einer großen Zahl multiplizieren, wie 1e20f? Um sicherzustellen, dass der Compiler sie nicht neu anordnet, können Sie eine noinline-Funktion no_reorder erstellen, die einfach ihr Argument zurückgibt, und dann no_reorder (a * 1e20f) * b verwenden. oder einfach eine Zahl zu einem Doppelklick (wenn es noch nicht ist) –

Antwort

7

Sie könnten std::signbit wie folgt verwenden:

bool c = std::signbit(a) == std::signbit(b); 

LIVE DEMO

Eine weitere Möglichkeit, std::copysign zu verwenden ist, wie folgt:

bool c = std::copysign(a,b) == a; 
+0

nicht genau zu überprüfen a * b <0. a und b kann auch 0 sein. Prüfe (1) a = 1, b = 0 (2) a = -1, b = 0 Beide sollten falsch sein. – user1899020

+0

@ user1899020 Wenn ich Ihre Frage richtig verstanden habe, erkennen sowohl "signbit" als auch "copysign" das Vorzeichenbit von Nullen, Unendlichkeiten und NaNs. – 101010

+0

@ user1899020 a und b sollten falsch als Nebeneffekt Ihres "schnellen Checks" sein, bedeutet aber nicht, dass es für verschiedene Zeichen falsch sein sollte. – Slava

0

Eine andere Lösung ist:

Bool c = ((0> a) = (0> b));