xml/libxml2libs/src/libxml2/libxml/libxml2_trionan.inc
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /*************************************************************************
       
     2  *
       
     3  * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
       
     4  *
       
     5  * Permission to use, copy, modify, and distribute this software for any
       
     6  * purpose with or without fee is hereby granted, provided that the above
       
     7  * copyright notice and this permission notice appear in all copies.
       
     8  *
       
     9  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
       
    10  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
       
    11  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
       
    12  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
       
    13  *
       
    14  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    15  ************************************************************************
       
    16  *
       
    17  * Functions to handle special quantities in floating-point numbers
       
    18  * (that is, NaNs and infinity). They provide the capability to detect
       
    19  * and fabricate special quantities.
       
    20  *
       
    21  * Although written to be as portable as possible, it can never be
       
    22  * guaranteed to work on all platforms, as not all hardware supports
       
    23  * special quantities.
       
    24  *
       
    25  * The approach used here (approximately) is to:
       
    26  *
       
    27  *   1. Use C99 functionality when available.
       
    28  *   2. Use IEEE 754 bit-patterns if possible.
       
    29  *   3. Use platform-specific techniques.
       
    30  *
       
    31  ************************************************************************/
       
    32 
       
    33 /*
       
    34  * 
       
    35  *  o Put all the magic into trio_fpclassify_and_signbit(), and use this from
       
    36  *    trio_isnan() etc.
       
    37  */
       
    38 
       
    39 /*************************************************************************
       
    40  * Include files
       
    41  */
       
    42 #include "xmlengtriodef.h"
       
    43 #include "xmlengtrionan.h"
       
    44 
       
    45 #include <math.h>
       
    46 #include <string.h>
       
    47 #include <limits.h>
       
    48 
       
    49 
       
    50 #if defined(TRIO_PLATFORM_UNIX)
       
    51 # include <signal.h>
       
    52 #endif
       
    53 #if defined(TRIO_COMPILER_DECC)
       
    54 #  if defined(__linux__)
       
    55 #   include <cpml.h>
       
    56 #  else
       
    57 #   include <fp_class.h>
       
    58 #  endif
       
    59 #endif
       
    60 #include <assert.h>
       
    61 
       
    62 #if defined(TRIO_DOCUMENTATION)
       
    63 # include "doc/doc_nan.h"
       
    64 #endif
       
    65 /** @addtogroup SpecialQuantities
       
    66     @{
       
    67 */
       
    68 
       
    69 /*************************************************************************
       
    70  * Definitions
       
    71  */
       
    72 
       
    73 #define TRIO_TRUE (1 == 1)
       
    74 #define TRIO_FALSE (0 == 1)
       
    75 
       
    76 /*
       
    77  * We must enable IEEE floating-point on Alpha
       
    78  */
       
    79  
       
    80 #if defined(__alpha) && !defined(_IEEE_FP)
       
    81 # if defined(TRIO_COMPILER_DECC)
       
    82 #  if defined(TRIO_PLATFORM_VMS)
       
    83 #   error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
       
    84 #  else
       
    85 #   if !defined(_CFE)
       
    86 #    error "Must be compiled with option -ieee"
       
    87 #   endif
       
    88 #  endif
       
    89 # elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
       
    90 #  error "Must be compiled with option -mieee"
       
    91 # endif
       
    92 #endif /* __alpha && ! _IEEE_FP */
       
    93 
       
    94 /*
       
    95  * In ANSI/IEEE 754-1985 64-bits double format numbers have the
       
    96  * following properties (amoungst others)
       
    97  *
       
    98  *   o FLT_RADIX == 2: binary encoding
       
    99  *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
       
   100  *     to indicate special numbers (e.g. NaN and Infinity), so the
       
   101  *     maximum exponent is 10 bits wide (2^10 == 1024).
       
   102  *   o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
       
   103  *     numbers are normalized the initial binary 1 is represented
       
   104  *     implicitly (the so-called "hidden bit"), which leaves us with
       
   105  *     the ability to represent 53 bits wide mantissa.
       
   106  */
       
   107 #if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53)
       
   108 # define USE_IEEE_754
       
   109 #endif
       
   110 
       
   111 #if defined(__SYMBIAN32__) || defined(WIN32)
       
   112 # define USE_IEEE_754
       
   113 #endif
       
   114 
       
   115 #ifndef DBL_MAX
       
   116 #define DBL_MAX 1.79769313486231500e+308
       
   117 #endif
       
   118 #ifndef DBL_MIN
       
   119 #define DBL_MIN 2.22507385850720200e-308
       
   120 #endif
       
   121 
       
   122 /*************************************************************************
       
   123  * Constants
       
   124  */
       
   125 
       
   126 #if defined(USE_IEEE_754)
       
   127 
       
   128 /*
       
   129  * Endian-agnostic indexing macro.
       
   130  *
       
   131  * The value of internalEndianMagic, when converted into a 64-bit
       
   132  * integer, becomes 0x0706050403020100 (we could have used a 64-bit
       
   133  * integer value instead of a double, but not all platforms supports
       
   134  * that type). The value is automatically encoded with the correct
       
   135  * endianess by the compiler, which means that we can support any
       
   136  * kind of endianess. The individual bytes are then used as an index
       
   137  * for the IEEE 754 bit-patterns and masks.
       
   138  */
       
   139 #define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
       
   140 
       
   141 
       
   142 
       
   143 static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
       
   144 
       
   145 /* Mask for the exponent */
       
   146 static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
       
   147   0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   148 };
       
   149 
       
   150 /* Mask for the mantissa */
       
   151 static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
       
   152   0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
       
   153 };
       
   154 
       
   155 /* Mask for the sign bit */
       
   156 static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
       
   157   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   158 };
       
   159 
       
   160 /* Bit-pattern for negative zero */
       
   161 static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
       
   162   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   163 };
       
   164 
       
   165 /* Bit-pattern for infinity */
       
   166 static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
       
   167   0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   168 };
       
   169 
       
   170 /* Bit-pattern for quiet NaN */
       
   171 static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
       
   172   0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   173 };
       
   174 
       
   175 
       
   176 /*************************************************************************
       
   177  * Functions
       
   178  */
       
   179 
       
   180 /*
       
   181  * trio_make_double
       
   182  */
       
   183 TRIO_PRIVATE double
       
   184 trio_make_double
       
   185 TRIO_ARGS1((values),
       
   186            TRIO_CONST unsigned char *values)
       
   187 {
       
   188   TRIO_VOLATILE double result;
       
   189   int i;
       
   190 
       
   191   for (i = 0; i < (int)sizeof(double); i++) {
       
   192     ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
       
   193   }
       
   194   return result;
       
   195 }
       
   196 
       
   197 /*
       
   198  * trio_is_special_quantity
       
   199  */
       
   200 TRIO_PRIVATE int
       
   201 trio_is_special_quantity
       
   202 TRIO_ARGS2((number, has_mantissa),
       
   203            double number,
       
   204            int *has_mantissa)
       
   205 {
       
   206   unsigned int i;
       
   207   unsigned char current;
       
   208   int is_special_quantity = TRIO_TRUE;
       
   209 
       
   210   *has_mantissa = 0;
       
   211 
       
   212   for (i = 0; i < (unsigned int)sizeof(double); i++) {
       
   213     current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
       
   214     is_special_quantity
       
   215       &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
       
   216     *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
       
   217   }
       
   218   return is_special_quantity;
       
   219 }
       
   220 
       
   221 /*
       
   222  * trio_is_negative
       
   223  */
       
   224 TRIO_PRIVATE int
       
   225 trio_is_negative
       
   226 TRIO_ARGS1((number),
       
   227            double number)
       
   228 {
       
   229   unsigned int i;
       
   230   int is_negative = TRIO_FALSE;
       
   231 
       
   232   for (i = 0; i < (unsigned int)sizeof(double); i++) {
       
   233     is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
       
   234                     & ieee_754_sign_mask[i]);
       
   235   }
       
   236   return is_negative;
       
   237 }
       
   238 
       
   239 #endif /* USE_IEEE_754 */
       
   240 
       
   241 
       
   242 /**
       
   243    Generate negative zero.
       
   244 
       
   245    @return Floating-point representation of negative zero.
       
   246 */
       
   247 TRIO_PUBLIC double
       
   248 trio_nzero(TRIO_NOARGS)
       
   249 {
       
   250 #if defined(USE_IEEE_754)
       
   251   return trio_make_double(ieee_754_negzero_array);
       
   252 #else
       
   253   TRIO_VOLATILE double zero = 0.0;
       
   254 
       
   255   return -zero;
       
   256 #endif
       
   257 }
       
   258 
       
   259 /**
       
   260    Generate positive infinity.
       
   261 
       
   262    @return Floating-point representation of positive infinity.
       
   263 */
       
   264 TRIO_PUBLIC double
       
   265 trio_pinf(TRIO_NOARGS)
       
   266 {
       
   267   /* Cache the result */
       
   268     //FIXIT
       
   269 //  static
       
   270       double result = 0.0;
       
   271 
       
   272   if (result == 0.0) {
       
   273 
       
   274 #if defined(INFINITY) && defined(__STDC_IEC_559__)
       
   275     result = (double)INFINITY;
       
   276 
       
   277 #elif defined(USE_IEEE_754)
       
   278     result = trio_make_double(ieee_754_infinity_array);
       
   279 
       
   280 #else
       
   281     /*
       
   282      * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
       
   283      * as infinity. Otherwise we have to resort to an overflow
       
   284      * operation to generate infinity.
       
   285      */
       
   286 # if defined(TRIO_PLATFORM_UNIX)
       
   287     void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
       
   288 # endif
       
   289 
       
   290     result = HUGE_VAL;
       
   291     if (HUGE_VAL == DBL_MAX) {
       
   292       /* Force overflow */
       
   293       result += HUGE_VAL;
       
   294     }
       
   295 
       
   296 # if defined(TRIO_PLATFORM_UNIX)
       
   297     signal(SIGFPE, signal_handler);
       
   298 # endif
       
   299 
       
   300 #endif
       
   301   }
       
   302   return result;
       
   303 }
       
   304 
       
   305 /**
       
   306    Generate negative infinity.
       
   307 
       
   308    @return Floating-point value of negative infinity.
       
   309 */
       
   310 TRIO_PUBLIC double
       
   311 trio_ninf(TRIO_NOARGS)
       
   312 {
       
   313     //FIXIT
       
   314   //static
       
   315       double result = 0.0;
       
   316 
       
   317   if (result == 0.0) {
       
   318     /*
       
   319      * Negative infinity is calculated by negating positive infinity,
       
   320      * which can be done because it is legal to do calculations on
       
   321      * infinity (for example,  1 / infinity == 0).
       
   322      */
       
   323     result = -trio_pinf();
       
   324   }
       
   325   return result;
       
   326 }
       
   327 
       
   328 /**
       
   329    Generate NaN.
       
   330 
       
   331    @return Floating-point representation of NaN.
       
   332 */
       
   333 TRIO_PUBLIC double
       
   334 trio_nan(TRIO_NOARGS)
       
   335 {
       
   336   /* Cache the result */
       
   337     //FIXIT
       
   338   //static
       
   339     double result = 0.0;
       
   340 
       
   341   if (result == 0.0) {
       
   342 
       
   343 #if defined(TRIO_COMPILER_SUPPORTS_C99)
       
   344     result = nan("");
       
   345 
       
   346 #elif defined(NAN) && defined(__STDC_IEC_559__)
       
   347     result = (double)NAN;
       
   348 
       
   349 #elif defined(USE_IEEE_754)
       
   350     result = trio_make_double(ieee_754_qnan_array);
       
   351 
       
   352 #else
       
   353     /*
       
   354      * There are several ways to generate NaN. The one used here is
       
   355      * to divide infinity by infinity. I would have preferred to add
       
   356      * negative infinity to positive infinity, but that yields wrong
       
   357      * result (infinity) on FreeBSD.
       
   358      *
       
   359      * This may fail if the hardware does not support NaN, or if
       
   360      * the Invalid Operation floating-point exception is unmasked.
       
   361      */
       
   362 # if defined(TRIO_PLATFORM_UNIX)
       
   363     void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
       
   364 # endif
       
   365 
       
   366     result = trio_pinf() / trio_pinf();
       
   367 
       
   368 # if defined(TRIO_PLATFORM_UNIX)
       
   369     signal(SIGFPE, signal_handler);
       
   370 # endif
       
   371 
       
   372 #endif
       
   373   }
       
   374   return result;
       
   375 }
       
   376 
       
   377 /**
       
   378    Check for NaN.
       
   379 
       
   380    @param number An arbitrary floating-point number.
       
   381    @return Boolean value indicating whether or not the number is a NaN.
       
   382 */
       
   383 TRIO_PUBLIC int
       
   384 trio_isnan
       
   385 TRIO_ARGS1((number),
       
   386            double number)
       
   387 {
       
   388 #if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
       
   389  || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
       
   390   /*
       
   391    * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
       
   392    * function. This function was already present in XPG4, but this
       
   393    * is a bit tricky to detect with compiler defines, so we choose
       
   394    * the conservative approach and only use it for UNIX95.
       
   395    */
       
   396   return isnan(number);
       
   397 
       
   398 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
       
   399   /*
       
   400    * Microsoft Visual C++ and Borland C++ Builder have an _isnan()
       
   401    * function.
       
   402    */
       
   403   return _isnan(number) ? TRIO_TRUE : TRIO_FALSE;
       
   404 
       
   405 #elif defined(USE_IEEE_754)
       
   406   /*
       
   407    * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
       
   408    * pattern, and a non-empty mantissa.
       
   409    */
       
   410   int has_mantissa;
       
   411   int is_special_quantity;
       
   412 
       
   413   is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
       
   414 
       
   415   return (is_special_quantity && has_mantissa);
       
   416 
       
   417 #else
       
   418   /*
       
   419    * Fallback solution
       
   420    */
       
   421   int status;
       
   422   double integral, fraction;
       
   423 
       
   424 # if defined(TRIO_PLATFORM_UNIX)
       
   425   void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
       
   426 # endif
       
   427 
       
   428   status = (/*
       
   429              * NaN is the only number which does not compare to itself
       
   430              */
       
   431             ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
       
   432             /*
       
   433              * Fallback solution if NaN compares to NaN
       
   434              */
       
   435             ((number != 0.0) &&
       
   436              (fraction = modf(number, &integral),
       
   437               integral == fraction)));
       
   438 
       
   439 # if defined(TRIO_PLATFORM_UNIX)
       
   440   signal(SIGFPE, signal_handler);
       
   441 # endif
       
   442 
       
   443   return status;
       
   444 
       
   445 #endif
       
   446 }
       
   447 
       
   448 /**
       
   449    Check for infinity.
       
   450 
       
   451    @param number An arbitrary floating-point number.
       
   452    @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
       
   453 */
       
   454 TRIO_PUBLIC int
       
   455 trio_isinf
       
   456 TRIO_ARGS1((number),
       
   457            double number)
       
   458 {
       
   459 #if defined(TRIO_COMPILER_DECC) && !defined(__linux__)
       
   460   /*
       
   461    * DECC has an isinf() macro, but it works differently than that
       
   462    * of C99, so we use the fp_class() function instead.
       
   463    */
       
   464   return ((fp_class(number) == FP_POS_INF)
       
   465           ? 1
       
   466           : ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
       
   467 
       
   468 #elif defined(isinf) && !defined(WIN32)
       
   469   /*
       
   470    * C99 defines isinf() as a macro.
       
   471    */
       
   472   return isinf(number)
       
   473     ? ((number > 0.0) ? 1 : -1)
       
   474     : 0;
       
   475 
       
   476 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
       
   477   /*
       
   478    * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
       
   479    * function that can be used to detect infinity.
       
   480    */
       
   481   return ((_fpclass(number) == _FPCLASS_PINF)
       
   482           ? 1
       
   483           : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0));
       
   484 
       
   485 #elif defined(USE_IEEE_754)
       
   486   /*
       
   487    * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
       
   488    * pattern, and an empty mantissa.
       
   489    */
       
   490   int has_mantissa;
       
   491   int is_special_quantity;
       
   492 
       
   493   is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
       
   494 
       
   495   return (is_special_quantity && !has_mantissa)
       
   496     ? ((number < 0.0) ? -1 : 1)
       
   497     : 0;
       
   498 
       
   499 #else
       
   500   /*
       
   501    * Fallback solution.
       
   502    */
       
   503   int status;
       
   504 
       
   505 # if defined(TRIO_PLATFORM_UNIX)
       
   506   void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
       
   507 # endif
       
   508 
       
   509   double infinity = trio_pinf();
       
   510 
       
   511   status = ((number == infinity)
       
   512             ? 1
       
   513             : ((number == -infinity) ? -1 : 0));
       
   514 
       
   515 # if defined(TRIO_PLATFORM_UNIX)
       
   516   signal(SIGFPE, signal_handler);
       
   517 # endif
       
   518 
       
   519   return status;
       
   520 
       
   521 #endif
       
   522 }
       
   523 
       
   524 #if 0
       
   525     /* Temporary  - this routine is not used anywhere */
       
   526 /**
       
   527    Check for finity.
       
   528 
       
   529    @param number An arbitrary floating-point number.
       
   530    @return Boolean value indicating whether or not the number is a finite.
       
   531 */
       
   532 TRIO_PUBLIC int
       
   533 trio_isfinite
       
   534 TRIO_ARGS1((number),
       
   535            double number)
       
   536 {
       
   537 #if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
       
   538   /*
       
   539    * C99 defines isfinite() as a macro.
       
   540    */
       
   541   return isfinite(number);
       
   542 
       
   543 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
       
   544   /*
       
   545    * Microsoft Visual C++ and Borland C++ Builder use _finite().
       
   546    */
       
   547   return _finite(number);
       
   548 
       
   549 #elif defined(USE_IEEE_754)
       
   550   /*
       
   551    * Examine IEEE 754 bit-pattern. For finity we do not care about the
       
   552    * mantissa.
       
   553    */
       
   554   int dummy;
       
   555 
       
   556   return (! trio_is_special_quantity(number, &dummy));
       
   557 
       
   558 #else
       
   559   /*
       
   560    * Fallback solution.
       
   561    */
       
   562   return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
       
   563 
       
   564 #endif
       
   565 }
       
   566 
       
   567 #endif
       
   568 
       
   569 /*
       
   570  * The sign of NaN is always false
       
   571  */
       
   572 TRIO_PUBLIC int
       
   573 trio_fpclassify_and_signbit
       
   574 TRIO_ARGS2((number, is_negative),
       
   575            double number,
       
   576            int *is_negative)
       
   577 {
       
   578 #if defined(fpclassify) && defined(signbit)
       
   579   /*
       
   580    * C99 defines fpclassify() and signbit() as a macros
       
   581    */
       
   582   *is_negative = signbit(number);
       
   583   switch (fpclassify(number)) {
       
   584   case FP_NAN:
       
   585     return TRIO_FP_NAN;
       
   586   case FP_INFINITE:
       
   587     return TRIO_FP_INFINITE;
       
   588   case FP_SUBNORMAL:
       
   589     return TRIO_FP_SUBNORMAL;
       
   590   case FP_ZERO:
       
   591     return TRIO_FP_ZERO;
       
   592   default:
       
   593     return TRIO_FP_NORMAL;
       
   594   }
       
   595 
       
   596 #else
       
   597 # if defined(TRIO_COMPILER_DECC)
       
   598   /*
       
   599    * DECC has an fp_class() function.
       
   600    */
       
   601 #  define TRIO_FPCLASSIFY(n) fp_class(n)
       
   602 #  define TRIO_QUIET_NAN FP_QNAN
       
   603 #  define TRIO_SIGNALLING_NAN FP_SNAN
       
   604 #  define TRIO_POSITIVE_INFINITY FP_POS_INF
       
   605 #  define TRIO_NEGATIVE_INFINITY FP_NEG_INF
       
   606 #  define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM
       
   607 #  define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM
       
   608 #  define TRIO_POSITIVE_ZERO FP_POS_ZERO
       
   609 #  define TRIO_NEGATIVE_ZERO FP_NEG_ZERO
       
   610 #  define TRIO_POSITIVE_NORMAL FP_POS_NORM
       
   611 #  define TRIO_NEGATIVE_NORMAL FP_NEG_NORM
       
   612 
       
   613 # elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
       
   614   /*
       
   615    * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
       
   616    * function.
       
   617    */
       
   618 #  define TRIO_FPCLASSIFY(n) _fpclass(n)
       
   619 #  define TRIO_QUIET_NAN _FPCLASS_QNAN
       
   620 #  define TRIO_SIGNALLING_NAN _FPCLASS_SNAN
       
   621 #  define TRIO_POSITIVE_INFINITY _FPCLASS_PINF
       
   622 #  define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF
       
   623 #  define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD
       
   624 #  define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND
       
   625 #  define TRIO_POSITIVE_ZERO _FPCLASS_PZ
       
   626 #  define TRIO_NEGATIVE_ZERO _FPCLASS_NZ
       
   627 #  define TRIO_POSITIVE_NORMAL _FPCLASS_PN
       
   628 #  define TRIO_NEGATIVE_NORMAL _FPCLASS_NN
       
   629 
       
   630 # elif defined(FP_PLUS_NORM)
       
   631   /*
       
   632    * HP-UX 9.x and 10.x have an fpclassify() function, that is different
       
   633    * from the C99 fpclassify() macro supported on HP-UX 11.x.
       
   634    *
       
   635    * AIX has class() for C, and _class() for C++, which returns the
       
   636    * same values as the HP-UX fpclassify() function.
       
   637    */
       
   638 #  if defined(TRIO_PLATFORM_AIX)
       
   639 #   if defined(__cplusplus)
       
   640 #    define TRIO_FPCLASSIFY(n) _class(n)
       
   641 #   else
       
   642 #    define TRIO_FPCLASSIFY(n) class(n)
       
   643 #   endif
       
   644 #  else
       
   645 #   define TRIO_FPCLASSIFY(n) fpclassify(n)
       
   646 #  endif
       
   647 #  define TRIO_QUIET_NAN FP_QNAN
       
   648 #  define TRIO_SIGNALLING_NAN FP_SNAN
       
   649 #  define TRIO_POSITIVE_INFINITY FP_PLUS_INF
       
   650 #  define TRIO_NEGATIVE_INFINITY FP_MINUS_INF
       
   651 #  define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM
       
   652 #  define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM
       
   653 #  define TRIO_POSITIVE_ZERO FP_PLUS_ZERO
       
   654 #  define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO
       
   655 #  define TRIO_POSITIVE_NORMAL FP_PLUS_NORM
       
   656 #  define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM
       
   657 # endif
       
   658 
       
   659 # if defined(TRIO_FPCLASSIFY)
       
   660   switch (TRIO_FPCLASSIFY(number)) {
       
   661   case TRIO_QUIET_NAN:
       
   662   case TRIO_SIGNALLING_NAN:
       
   663     *is_negative = TRIO_FALSE; /* NaN has no sign */
       
   664     return TRIO_FP_NAN;
       
   665   case TRIO_POSITIVE_INFINITY:
       
   666     *is_negative = TRIO_FALSE;
       
   667     return TRIO_FP_INFINITE;
       
   668   case TRIO_NEGATIVE_INFINITY:
       
   669     *is_negative = TRIO_TRUE;
       
   670     return TRIO_FP_INFINITE;
       
   671   case TRIO_POSITIVE_SUBNORMAL:
       
   672     *is_negative = TRIO_FALSE;
       
   673     return TRIO_FP_SUBNORMAL;
       
   674   case TRIO_NEGATIVE_SUBNORMAL:
       
   675     *is_negative = TRIO_TRUE;
       
   676     return TRIO_FP_SUBNORMAL;
       
   677   case TRIO_POSITIVE_ZERO:
       
   678     *is_negative = TRIO_FALSE;
       
   679     return TRIO_FP_ZERO;
       
   680   case TRIO_NEGATIVE_ZERO:
       
   681     *is_negative = TRIO_TRUE;
       
   682     return TRIO_FP_ZERO;
       
   683   case TRIO_POSITIVE_NORMAL:
       
   684     *is_negative = TRIO_FALSE;
       
   685     return TRIO_FP_NORMAL;
       
   686   case TRIO_NEGATIVE_NORMAL:
       
   687     *is_negative = TRIO_TRUE;
       
   688     return TRIO_FP_NORMAL;
       
   689   default:
       
   690     /* Just in case... */
       
   691     *is_negative = (number < 0.0);
       
   692     return TRIO_FP_NORMAL;
       
   693   }
       
   694 
       
   695 # else
       
   696   /*
       
   697    * Fallback solution.
       
   698    */
       
   699   int rc;
       
   700 
       
   701   if (number == 0.0) {
       
   702     /*
       
   703      * In IEEE 754 the sign of zero is ignored in comparisons, so we
       
   704      * have to handle this as a special case by examining the sign bit
       
   705      * directly.
       
   706      */
       
   707 #  if defined(USE_IEEE_754)
       
   708     *is_negative = trio_is_negative(number);
       
   709 #  else
       
   710     *is_negative = TRIO_FALSE; 
       
   711 #  endif
       
   712     return TRIO_FP_ZERO;
       
   713   }
       
   714   if (trio_isnan(number)) {
       
   715     *is_negative = TRIO_FALSE;
       
   716     return TRIO_FP_NAN;
       
   717   }
       
   718   rc = trio_isinf(number);
       
   719   if (rc) {
       
   720     *is_negative = (rc == -1);
       
   721     return TRIO_FP_INFINITE;
       
   722   }
       
   723   if ((number > 0.0) && (number < DBL_MIN)) {
       
   724     *is_negative = TRIO_FALSE;
       
   725     return TRIO_FP_SUBNORMAL;
       
   726   }
       
   727   if ((number < 0.0) && (number > -DBL_MIN)) {
       
   728     *is_negative = TRIO_TRUE;
       
   729     return TRIO_FP_SUBNORMAL;
       
   730   }
       
   731   *is_negative = (number < 0.0);
       
   732   return TRIO_FP_NORMAL;
       
   733 
       
   734 # endif
       
   735 #endif
       
   736 }
       
   737 
       
   738 /**
       
   739    Examine the sign of a number.
       
   740 
       
   741    @param number An arbitrary floating-point number.
       
   742    @return Boolean value indicating whether or not the number has the
       
   743    sign bit set (i.e. is negative).
       
   744 */
       
   745 TRIO_PUBLIC int
       
   746 trio_signbit
       
   747 TRIO_ARGS1((number),
       
   748            double number)
       
   749 {
       
   750   int is_negative;
       
   751 
       
   752   (void)trio_fpclassify_and_signbit(number, &is_negative);
       
   753   return is_negative;
       
   754 }
       
   755 
       
   756 #if 0
       
   757     /* Temporary  - this routine is not used in libxml */
       
   758 /**
       
   759    Examine the class of a number.
       
   760 
       
   761    @param number An arbitrary floating-point number.
       
   762    @return Enumerable value indicating the class of @p number
       
   763 */
       
   764 TRIO_PUBLIC int
       
   765 trio_fpclassify
       
   766 TRIO_ARGS1((number),
       
   767            double number)
       
   768 {
       
   769   int dummy;
       
   770 
       
   771   return trio_fpclassify_and_signbit(number, &dummy);
       
   772 }
       
   773 
       
   774 #endif
       
   775 
       
   776 /** @} SpecialQuantities */
       
   777 
       
   778 /*************************************************************************
       
   779  * For test purposes.
       
   780  *
       
   781  * Add the following compiler option to include this test code.
       
   782  *
       
   783  *  Unix : -DSTANDALONE
       
   784  *  VMS  : /DEFINE=(STANDALONE)
       
   785  */
       
   786 #if defined(STANDALONE)
       
   787 # include <stdio.h>
       
   788 
       
   789 static TRIO_CONST char *
       
   790 getClassification
       
   791 TRIO_ARGS1((type),
       
   792            int type)
       
   793 {
       
   794   switch (type) {
       
   795   case TRIO_FP_INFINITE:
       
   796     return "FP_INFINITE";
       
   797   case TRIO_FP_NAN:
       
   798     return "FP_NAN";
       
   799   case TRIO_FP_NORMAL:
       
   800     return "FP_NORMAL";
       
   801   case TRIO_FP_SUBNORMAL:
       
   802     return "FP_SUBNORMAL";
       
   803   case TRIO_FP_ZERO:
       
   804     return "FP_ZERO";
       
   805   default:
       
   806     return "FP_UNKNOWN";
       
   807   }
       
   808 }
       
   809 
       
   810 static void
       
   811 print_class
       
   812 TRIO_ARGS2((prefix, number),
       
   813            TRIO_CONST char *prefix,
       
   814            double number)
       
   815 {
       
   816   printf("%-6s: %s %-15s %g\n",
       
   817          prefix,
       
   818          trio_signbit(number) ? "-" : "+",
       
   819          getClassification(TRIO_FPCLASSIFY(number)),
       
   820          number);
       
   821 }
       
   822 
       
   823 
       
   824 int main(TRIO_NOARGS)
       
   825 {
       
   826   double my_nan;
       
   827   double my_pinf;
       
   828   double my_ninf;
       
   829 # if defined(TRIO_PLATFORM_UNIX)
       
   830   void (*signal_handler) TRIO_PROTO((int));
       
   831 # endif
       
   832 
       
   833   my_nan = trio_nan();
       
   834   my_pinf = trio_pinf();
       
   835   my_ninf = trio_ninf();
       
   836 
       
   837   print_class("Nan", my_nan);
       
   838   print_class("PInf", my_pinf);
       
   839   print_class("NInf", my_ninf);
       
   840   print_class("PZero", 0.0);
       
   841   print_class("NZero", -0.0);
       
   842   print_class("PNorm", 1.0);
       
   843   print_class("NNorm", -1.0);
       
   844   print_class("PSub", 1.01e-307 - 1.00e-307);
       
   845   print_class("NSub", 1.00e-307 - 1.01e-307);
       
   846 
       
   847   printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   848          my_nan,
       
   849          ((unsigned char *)&my_nan)[0],
       
   850          ((unsigned char *)&my_nan)[1],
       
   851          ((unsigned char *)&my_nan)[2],
       
   852          ((unsigned char *)&my_nan)[3],
       
   853          ((unsigned char *)&my_nan)[4],
       
   854          ((unsigned char *)&my_nan)[5],
       
   855          ((unsigned char *)&my_nan)[6],
       
   856          ((unsigned char *)&my_nan)[7],
       
   857          trio_isnan(my_nan), trio_isinf(my_nan));
       
   858   printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   859          my_pinf,
       
   860          ((unsigned char *)&my_pinf)[0],
       
   861          ((unsigned char *)&my_pinf)[1],
       
   862          ((unsigned char *)&my_pinf)[2],
       
   863          ((unsigned char *)&my_pinf)[3],
       
   864          ((unsigned char *)&my_pinf)[4],
       
   865          ((unsigned char *)&my_pinf)[5],
       
   866          ((unsigned char *)&my_pinf)[6],
       
   867          ((unsigned char *)&my_pinf)[7],
       
   868          trio_isnan(my_pinf), trio_isinf(my_pinf));
       
   869   printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   870          my_ninf,
       
   871          ((unsigned char *)&my_ninf)[0],
       
   872          ((unsigned char *)&my_ninf)[1],
       
   873          ((unsigned char *)&my_ninf)[2],
       
   874          ((unsigned char *)&my_ninf)[3],
       
   875          ((unsigned char *)&my_ninf)[4],
       
   876          ((unsigned char *)&my_ninf)[5],
       
   877          ((unsigned char *)&my_ninf)[6],
       
   878          ((unsigned char *)&my_ninf)[7],
       
   879          trio_isnan(my_ninf), trio_isinf(my_ninf));
       
   880 
       
   881 # if defined(TRIO_PLATFORM_UNIX)
       
   882   signal_handler = signal(SIGFPE, SIG_IGN);
       
   883 # endif
       
   884 
       
   885   my_pinf = DBL_MAX + DBL_MAX;
       
   886   my_ninf = -my_pinf;
       
   887   my_nan = my_pinf / my_pinf;
       
   888 
       
   889 # if defined(TRIO_PLATFORM_UNIX)
       
   890   signal(SIGFPE, signal_handler);
       
   891 # endif
       
   892 
       
   893   printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   894          my_nan,
       
   895          ((unsigned char *)&my_nan)[0],
       
   896          ((unsigned char *)&my_nan)[1],
       
   897          ((unsigned char *)&my_nan)[2],
       
   898          ((unsigned char *)&my_nan)[3],
       
   899          ((unsigned char *)&my_nan)[4],
       
   900          ((unsigned char *)&my_nan)[5],
       
   901          ((unsigned char *)&my_nan)[6],
       
   902          ((unsigned char *)&my_nan)[7],
       
   903          trio_isnan(my_nan), trio_isinf(my_nan));
       
   904   printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   905          my_pinf,
       
   906          ((unsigned char *)&my_pinf)[0],
       
   907          ((unsigned char *)&my_pinf)[1],
       
   908          ((unsigned char *)&my_pinf)[2],
       
   909          ((unsigned char *)&my_pinf)[3],
       
   910          ((unsigned char *)&my_pinf)[4],
       
   911          ((unsigned char *)&my_pinf)[5],
       
   912          ((unsigned char *)&my_pinf)[6],
       
   913          ((unsigned char *)&my_pinf)[7],
       
   914          trio_isnan(my_pinf), trio_isinf(my_pinf));
       
   915   printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
       
   916          my_ninf,
       
   917          ((unsigned char *)&my_ninf)[0],
       
   918          ((unsigned char *)&my_ninf)[1],
       
   919          ((unsigned char *)&my_ninf)[2],
       
   920          ((unsigned char *)&my_ninf)[3],
       
   921          ((unsigned char *)&my_ninf)[4],
       
   922          ((unsigned char *)&my_ninf)[5],
       
   923          ((unsigned char *)&my_ninf)[6],
       
   924          ((unsigned char *)&my_ninf)[7],
       
   925          trio_isnan(my_ninf), trio_isinf(my_ninf));
       
   926 
       
   927   return 0;
       
   928 }
       
   929 #endif
       
   930