2009-07-07 11 views
14

chiunque può descrivere la differenza di comportamento tra BOOST_CHECK_CLOSE e BOOST_CHECK_CLOSE_FRACTION? The documentation implica che entrambe le macro trattino il loro terzo parametro in modo identico, il che mi fa sospettare che la documentazione sia errata.Differenza tra BOOST_CHECK_CLOSE e BOOST_CHECK_CLOSE_FRACTION?

In particolare, BOOST_CHECK_CLOSE_FRACTION mi dà qualche strani risultati cercando:

error in "...": difference between *expected{0} and *actual{-1.7763568394002506e-16} exceeds 9.9999999999999995e-07 

c'è un Gotcha perché mi aspetto un risultato pari a zero? Non ho avuto successo nel leggere le dichiarazioni macro sottostanti. Nota: BOOST_CHECK_SMALL non è appropriato per il mio caso d'uso (confronto di due vettori dopo un'operazione di algebra lineare).

risposta

6

In base a this discussion, uno (BOOST_CHECK_CLOSE) tratta il terzo parametro come espressione di una percentuale, mentre l'altro (BOOST_CHECK_CLOSE_FRACTION) lo considera come espressione di una frazione. Quindi, 01 nel primo dovrebbe essere equivalente a 0,0001 nel secondo.

Non certo se che spiega il vostro problema - si ottiene lo stesso risultato dispari con BOOST_CHECK_CLOSE? Non sarei scioccato se lo 0 causasse un problema, ma non ho esperienza di prima mano con i macro.

+1

Grazie per la risposta. Sembra che lo zero causi il problema e che un comportamento simile si verifichi con un argomento zero sia per BOOST \ _CHECK \ _CLOSE che BOOST \ _CHECK \ _CLOSE \ _FRACTION –

5

Sì. Zero non è "vicino" a nessun valore. Puoi invece utilizzare BOOST_CHECK_SMALL.

1

@Gennadiy: Zero può essere vicino a qualsiasi valore piccolo . :-) relativi differenze crescono arbitrariamente grande se il valore atteso è molto vicino a zero.

Ecco una funzione soluzione che utilizzo per valori doppi unità-test: se il valore atteso è molto piccolo o nullo allora verificare la piccolezza del valore osservato, altrimenti controllare vicinanza:

void dbl_check_close(
    double expected, double observed, 
    double small, double pct_tol 
) { 
    if (std::fabs(expected) < small) { 
     BOOST_CHECK_SMALL(observed, small); 
    } else { 
     BOOST_CHECK_CLOSE(expected, observed, pct_tol); 
    } 
} 

Di Ovviamente sarebbe bello avere una macro BOOST_CHECK_SMALL_OR_CLOSE che lo faccia automaticamente. Gennadiy potrebbe forse parlare con l'autore del Boost.Test ;-)