2015-12-01 21 views
13

Ho due numeri in virgola mobile a e b. Voglio controllare se hanno segni diversi. Il modo più semplice è quello di vedereUn modo semplice per verificare se due numeri hanno segni diversi?

bool b = a * b < 0; 

ma i due numeri sono molto piccoli e a * b potrebbe essere underflow. Qualche altro modo semplice per controllarlo?

Chiunque pensi che sia una domanda doppia, per favore, forniscimi una risposta che corrisponda esattamente alla condizione a * b < 0. Nota qui il segno di 0 non è definito nella mia domanda.

+4

C++ 11 ha [signbit] (http://en.cppreference.com/w/cpp/numeric/math/signbit). Quindi, qualcosa 'signbit (a) == signbit (b)' sarà vero con entrambi hanno lo stesso segno. – wendelbsilva

+0

fwiw, vs2012 non sembra avere un segnale. Il 2013 sì, però. non puoi semplicemente moltiplicare un numero con un numero grande, come 1e20f? per assicurarti che il compilatore non lo riordini, puoi creare una funzione noinline no_reorder che restituisce semplicemente il suo argomento, e quindi usa no_reorder (a * 1e20f) * b. o semplicemente un numero a un doppio (se non lo è ancora) –

risposta

7

Si potrebbe utilizzare std::signbit come segue:

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

LIVE DEMO

Un altro modo è quello di utilizzare std::copysign come segue:

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

non esatto per controllare a * b <0. aeb anche a 0. Controllare (1) a = 1, b = 0 (2) a = -1, b = 0 Entrambi devono essere falsi. – user1899020

+0

@ user1899020 Se ho risposto correttamente alla tua domanda, sia 'signbit' che' copysign' rilevano il bit di segno di zeri, infiniti e NaN. – 101010

+0

@ user1899020 aeb dovrebbe essere falso come effetto collaterale del "controllo rapido" ma non significa che dovrebbe essere falso per segni diversi – Slava

0

Un'altra soluzione è:

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