   detecting NANs
  whats the best way of checking wether a number is a NAN (+ other fp specials)?also stl::sort isnt meant to break if u include fp specials is it?ta zedfurther info after a searchQuote:The floating-point data types (float anddouble) contain a value NaN (not-a-number) that possesses some remarkableproperties. The IEEE 754 standard requires that every comparison (==, <, >, <=, >=)involving NaN should return false. This was a terrible decision that overruled themeaning of equality and made it difficult to do any careful reasoning about programs.yes it was a bad idea   
  http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.15   ;  thanks Boder any idea how stl::sort etc (since sort uses the == function) handles it i would hope + assume that all NANs would get stuck at the end, is this correct?;Quote:Original post by zedzeekwhats the best way of checking wether a number is a NAN (+ other fp specials)?x != x will be true if and only if x is NaN.   ;  I would write a small test program.   ;Quote:Original post by zedzeekthanks Boder any idea how stl::sort etc (since sort uses the == function) handles it i would hope + assume that all NANs would get stuck at the end, is this correct?No, they typically use operator<() to establish a Strict Weak Ordering (q.v. SGI docs).Two values are equivalent (not equal!) if a < b and b < a both are false.This makes NaN equivalent to any other number...If you do expect NaNs, use your own comparison function:template<class Float>struct less_NaN :   public std::binary_function<Float, Float, bool>{   bool operator()(const Float& lhs, const Float& rhs) const   {  bool lhs_is_NaN = (lhs != lhs);  bool rhs_is_NaN = (rhs != rhs);  // Normal case  if (!lhs_is_NaN && !rhs_is_NaN)return lhs < rhs;  // make NaN smaller than nothing  return !lhs_is_NaN;   }};[Edited by - Fruny on June 21, 2006 1:38:23 AM];  Here's my test. Doesn't compile on VC++ but it does on G++.#include <vector>#include <algorithm>#include <limits>#include <iostream>const float nan = 0.0f/0.0f;const float inf = 1.0f/0.0f;int main(){std::vector< float > floatVec;floatVec.push_back(nan);floatVec.push_back(1.0f);floatVec.push_back(inf);floatVec.push_back(2.0f);floatVec.push_back(nan);std::sort( floatVec.begin(), floatVec.end() );std::cout << "Sorted Contents:" << std::endl;for( std::vector< float >::const_iterator itr = floatVec.begin();itr != floatVec.end();++itr ){  std::cout << *itr << ", ";}std::cout << std::endl;return 0;}Ouput:$ ./a.exe Sorted Contents:-1.#IND, 1, 2, 1.#INF, -1.#IND, You can see the NaN's don't move.   ;Quote:Original post by zedzeekwhats the best way of checking wether a number is a NAN (+ other fp specials)?This works for me:if( isnan( number ) )   cout << "Number is a NaN" << endl;;  NaN-aware version of Boder's test, with fallback to std::less<T> for types which do not have NaNs.#include <iostream>#include <vector>#include <algorithm>#include <limits>#include <functional>namespace ftl{template<class T>struct less_NaN :public ::std::binary_function<T, T, bool>{   bool operator()(const T& lhs, const T& rhs) const   {   bool lhs_is_NaN = (lhs != lhs);   bool rhs_is_NaN = (rhs != rhs);   if (!lhs_is_NaN && !rhs_is_NaN)  return lhs < rhs;   return !lhs_is_NaN;   }};template<class T>struct has_NaN{static const bool value = std::numeric_limits<T>::is_iec559 ||  std::numeric_limits<T>::has_quiet_NaN ||  std::numeric_limits<T>::has_signaling_NaN;};namespace detail{template<class T, bool has_NaN>struct less_helper{typedef typename ::std::less<T> type;};template<class T>struct less_helper<T, true>{typedef typename less_NaN<T> type;};}template<class T>struct less :public detail::less_helper<T, has_NaN<T>::value>::type{};}const float nan = std::numeric_limits<float>::quiet_NaN();const float inf = std::numeric_limits<float>::infinity();int main(){std::vector< float > floatVec;floatVec.push_back(nan);floatVec.push_back(1.0f);floatVec.push_back(inf);floatVec.push_back(2.0f);floatVec.push_back(nan);std::sort( floatVec.begin(), floatVec.end(), ftl::less<float>() );std::cout << "Sorted Contents:" << std::endl;for( std::vector< float >::const_iterator itr = floatVec.begin(); itr != floatVec.end(); ++itr ){  std::cout << *itr << ", ";}std::cout << std::endl;return 0;}Prints:Sorted Contents:1, 2, 1.#INF, 1.#QNAN, 1.#QNAN,;  Or, as a simpler alternative solution, first move all the NaNs at the end:struct is_not_nan :    public std::unary_function<T, bool>{    bool operator()(const T& val) const    {   return val == val;    }};...std::vector<float>::iterator first_nan = std::partition( floatVec.begin(), floatVec.end(), is_not_nan<float>() );std::sort( floatVec.begin(), first_nan );