Nan, Infinity Etc.

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Nan, Infinity Etc.

Post by Baker »

Up to this point, I've never really done anything that could potentially have these as results (if the code was debugged or handled the exceptions right).

Enter geometry and having to deal with the possibility of infinite slope, which have situations where division by 0 can happen and must somehow be stored.

Code: Select all

#define isnormal(x)    \
    (    sizeof (x) == sizeof(float )    ?    __inline_isnormalf((float)(x))    \
    :    sizeof (x) == sizeof(double)    ?    __inline_isnormald((double)(x))    \
                                        :    __inline_isnormal ((long double)(x)))

#define isfinite(x)    \
    (    sizeof (x) == sizeof(float )    ?    __inline_isfinitef((float)(x))    \
    :    sizeof (x) == sizeof(double)    ?    __inline_isfinited((double)(x))    \
                                        :    __inline_isfinite ((long double)(x)))

#define isinf(x)    \
    (    sizeof (x) == sizeof(float )    ?    __inline_isinff((float)(x))    \
    :    sizeof (x) == sizeof(double)    ?    __inline_isinfd((double)(x))    \
                                        :    __inline_isinf ((long double)(x)))

#define isnan(x)    \
    (    sizeof (x) == sizeof(float )    ?    __inline_isnanf((float)(x))    \
    :    sizeof (x) == sizeof(double)    ?    __inline_isnand((double)(x))    \
                                        :    __inline_isnan ((long double)(x)))

#define signbit(x)    \
    (    sizeof (x) == sizeof(float )    ?    __inline_signbitf((float)(x))    \
    :    sizeof (x) == sizeof(double)    ?    __inline_signbitd((double)(x))    \
                                        :    __inline_signbit((long double)(x)))
As far as I have been able to tell, these are IEEE 754 floating point standard but only for C99 (and possibly GNUC specific?)
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Nan, Infinity Etc.

Post by revelator »

hmm on gnu its gcc specific it seems.

Code: Select all

#if _GLIBCXX_USE_C99_MATH
#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC

  /// Function template definitions [8.16.3].
  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    fpclassify(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
				  FP_SUBNORMAL, FP_ZERO, __type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isfinite(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isfinite(__type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isinf(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isinf(__type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isnan(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isnan(__type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isnormal(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isnormal(__type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    signbit(_Tp __f)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_signbit(__type(__f));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isgreater(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isgreater(__type(__f1), __type(__f2));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isgreaterequal(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isgreaterequal(__type(__f1), __type(__f2));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isless(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isless(__type(__f1), __type(__f2));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    islessequal(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_islessequal(__type(__f1), __type(__f2));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    islessgreater(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_islessgreater(__type(__f1), __type(__f2));
    }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value,
					   int>::__type
    isunordered(_Tp __f1, _Tp __f2)
    {
      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
      return __builtin_isunordered(__type(__f1), __type(__f2));
    }

#endif
#endif
the above from gcc's internal c++ headers.
Productivity is a state of mind.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Nan, Infinity Etc.

Post by Baker »

The more I think about this, the less I like the idea of this.

Maybe I'll just add some extra flag to a struct, use a macro to check for weird values within the struct, and if in some future date some real solution that can be expected to operate properly on any platform, just change the definition of the macro.

After reading up more and more on this, the solutions all look essentially terrible.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
andrewj
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Re: Nan, Infinity Etc.

Post by andrewj »

Baker wrote:The more I think about this, the less I like the idea of this.
Yeah I don't like it either, for me the NaN and infinities are more like error results rather than genuinely useful values, and any code that uses them may suffer portabilities problems (portability to different Oses, different compilers or different languages).
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Nan, Infinity Etc.

Post by Baker »

I'll probably make functions that return pointers and then the returned pointer can check and see if it is a special address being pointed to. That keeps things in the "if (result == NULL)" family.

Code: Select all

if (result == RESULT_NAN)
I read that the behavior of floating point return values for special cases can vary per-processor. Intel, AMD, RISC (game consoles), MIPS (PSP), ARM (mobile). So ... is mess to avoid ... yes. This is without bringing up compiler compatibility, etc.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
taniwha
Posts: 401
Joined: Thu Jan 14, 2010 7:11 am
Contact:

Re: Nan, Infinity Etc.

Post by taniwha »

First, I agree: best to avoid using nan and inf. They seem to be best for indicating bad input (and to a certain extent, the nature of the badness).

One problem with nan is nan is never equal to anything, even nan (ie, comparison always fails).

Inf is sort of useful: you can compare against it (so it's good for initializing min/max (you have + and - inf)), but that's about it. Forget doing any actual math with inf. I had the bright idea of using inf for initializing windings in qf's bsp compiler. Worked wonderfully for min/max but broke completely for clipping.
Leave others their otherness.
http://quakeforge.net/
Post Reply