⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trionan.c

📁 一个C语言写的快速贝叶斯垃圾邮件过滤工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************* * * $Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $ * * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************ * * Functions to handle special quantities in floating-point numbers * (that is, NaNs and infinity). They provide the capability to detect * and fabricate special quantities. * * Although written to be as portable as possible, it can never be * guaranteed to work on all platforms, as not all hardware supports * special quantities. * * The approach used here (approximately) is to: * *   1. Use C99 functionality when available. *   2. Use IEEE 754 bit-patterns if possible. *   3. Use platform-specific techniques. * ************************************************************************//************************************************************************* * Include files */#include "triodef.h"#include "trionan.h"#include <math.h>#include <string.h>#include <limits.h>#if !defined(TRIO_PLATFORM_SYMBIAN)# include <float.h>#endif#if defined(TRIO_PLATFORM_UNIX)# include <signal.h>#endif#if defined(TRIO_COMPILER_DECC)# include <fp_class.h>#endif#include <assert.h>#if defined(TRIO_DOCUMENTATION)# include "doc/doc_nan.h"#endif/** @addtogroup SpecialQuantities    @{*//************************************************************************* * Definitions */#if !defined(TRIO_PUBLIC_NAN)# define TRIO_PUBLIC_NAN TRIO_PUBLIC#endif#if !defined(TRIO_PRIVATE_NAN)# define TRIO_PRIVATE_NAN TRIO_PRIVATE#endif#define TRIO_TRUE (1 == 1)#define TRIO_FALSE (0 == 1)/* * We must enable IEEE floating-point on Alpha */#if defined(__alpha) && !defined(_IEEE_FP)# if defined(TRIO_COMPILER_DECC)#  if defined(TRIO_PLATFORM_VMS)#   error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"#  else#   if !defined(_CFE)#    error "Must be compiled with option -ieee"#   endif#  endif# else#  if defined(TRIO_COMPILER_GCC)#   error "Must be compiled with option -mieee"#  endif# endif#endif /* __alpha && ! _IEEE_FP *//* * In ANSI/IEEE 754-1985 64-bits double format numbers have the * following properties (amoungst others) * *   o FLT_RADIX == 2: binary encoding *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used *     to indicate special numbers (e.g. NaN and Infinity), so the *     maximum exponent is 10 bits wide (2^10 == 1024). *   o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because *     numbers are normalized the initial binary 1 is represented *     implicitly (the so-called "hidden bit"), which leaves us with *     the ability to represent 53 bits wide mantissa. */#if defined(__STDC_IEC_559__)# define TRIO_IEEE_754#else# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)#  define TRIO_IEEE_754# endif#endif/* * Determine which fpclassify_and_sign() function to use. */#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)#  define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT# else#  if defined(TRIO_COMPILER_DECC)#   define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT#  else#   if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)#    define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT#   else#    if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)#     define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT#    else#     if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)#      define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT#     else#      define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT#     endif#    endif#   endif#  endif# endif#endif/* * Determine how to generate negative zero. */#if defined(TRIO_FUNC_NZERO)# if defined(TRIO_IEEE_754)#  define TRIO_NZERO_IEEE_754# else#  define TRIO_NZERO_FALLBACK# endif#endif/* * Determine how to generate positive infinity. */#if defined(TRIO_FUNC_PINF)# if defined(INFINITY) && defined(__STDC_IEC_559__)#  define TRIO_PINF_C99_MACRO# else#  if defined(TRIO_IEEE_754)#   define TRIO_PINF_IEEE_754#  else#   define TRIO_PINF_FALLBACK#  endif# endif#endif/* * Determine how to generate NaN. */#if defined(TRIO_FUNC_NAN)# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)#  define TRIO_NAN_C99_FUNCTION# else#  if defined(NAN) && defined(__STDC_IEC_559__)#   define TRIO_NAN_C99_MACRO#  else#   if defined(TRIO_IEEE_754)#    define TRIO_NAN_IEEE_754#   else#    define TRIO_NAN_FALLBACK#   endif#  endif# endif#endif/* * Resolve internal dependencies. */#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)# define TRIO_FUNC_INTERNAL_ISNAN# define TRIO_FUNC_INTERNAL_ISINF# if defined(TRIO_IEEE_754)#  define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY#  define TRIO_FUNC_INTERNAL_IS_NEGATIVE# endif#endif#if defined(TRIO_NZERO_IEEE_754) \ || defined(TRIO_PINF_IEEE_754) \ || defined(TRIO_NAN_IEEE_754)# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE#endif#if defined(TRIO_FUNC_INTERNAL_ISNAN)# if defined(PREDEF_STANDARD_XPG3)#  define TRIO_INTERNAL_ISNAN_XPG3# else#  if defined(TRIO_IEEE_754)#   define TRIO_INTERNAL_ISNAN_IEEE_754#  else#   define TRIO_INTERNAL_ISNAN_FALLBACK#  endif# endif#endif#if defined(TRIO_FUNC_INTERNAL_ISINF)# if defined(TRIO_IEEE_754)#  define TRIO_INTERNAL_ISINF_IEEE_754# else#  define TRIO_INTERNAL_ISINF_FALLBACK# endif#endif/************************************************************************* * Constants */#if !defined(TRIO_EMBED_NAN)static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";#endif#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \ || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \ || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)/* * Endian-agnostic indexing macro. * * The value of internalEndianMagic, when converted into a 64-bit * integer, becomes 0x0706050403020100 (we could have used a 64-bit * integer value instead of a double, but not all platforms supports * that type). The value is automatically encoded with the correct * endianess by the compiler, which means that we can support any * kind of endianess. The individual bytes are then used as an index * for the IEEE 754 bit-patterns and masks. */#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;#endif#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)/* Mask for the exponent */static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/* Mask for the mantissa */static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};#endif#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)/* Mask for the sign bit */static TRIO_CONST unsigned char ieee_754_sign_mask[] = {  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#endif#if defined(TRIO_NZERO_IEEE_754)/* Bit-pattern for negative zero */static TRIO_CONST unsigned char ieee_754_negzero_array[] = {  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#endif#if defined(TRIO_PINF_IEEE_754)/* Bit-pattern for infinity */static TRIO_CONST unsigned char ieee_754_infinity_array[] = {  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#endif#if defined(TRIO_NAN_IEEE_754)/* Bit-pattern for quiet NaN */static TRIO_CONST unsigned char ieee_754_qnan_array[] = {  0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#endif/************************************************************************* * Internal functions *//* * internal_make_double */#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)TRIO_PRIVATE_NAN doubleinternal_make_doubleTRIO_ARGS1((values),	   TRIO_CONST unsigned char *values){  TRIO_VOLATILE double result;  int i;  for (i = 0; i < (int)sizeof(double); i++) {    ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];  }  return result;}#endif/* * internal_is_special_quantity */#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)TRIO_PRIVATE_NAN intinternal_is_special_quantityTRIO_ARGS2((number, has_mantissa),	   double number,	   int *has_mantissa){  unsigned int i;  unsigned char current;  int is_special_quantity = TRIO_TRUE;  *has_mantissa = 0;  for (i = 0; i < (unsigned int)sizeof(double); i++) {    current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];    is_special_quantity      &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);    *has_mantissa |= (current & ieee_754_mantissa_mask[i]);  }  return is_special_quantity;}#endif/* * internal_is_negative */#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)TRIO_PRIVATE_NAN intinternal_is_negativeTRIO_ARGS1((number),	   double number){  unsigned int i;  int is_negative = TRIO_FALSE;  for (i = 0; i < (unsigned int)sizeof(double); i++) {    is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]		    & ieee_754_sign_mask[i]);  }  return is_negative;}#endif#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)TRIO_PRIVATE_NAN TRIO_INLINE intc99_fpclassify_and_signbitTRIO_ARGS2((number, is_negative),	   double number,	   int *is_negative){  *is_negative = signbit(number);  switch (fpclassify(number)) {  case FP_NAN:    return TRIO_FP_NAN;  case FP_INFINITE:    return TRIO_FP_INFINITE;  case FP_SUBNORMAL:    return TRIO_FP_SUBNORMAL;  case FP_ZERO:    return TRIO_FP_ZERO;  default:    return TRIO_FP_NORMAL;  }}#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)TRIO_PRIVATE_NAN TRIO_INLINE intdecc_fpclassify_and_signbitTRIO_ARGS2((number, is_negative),	  double number,	  int *is_negative){  switch (fp_class(number)) {  case FP_QNAN:  case FP_SNAN:    *is_negative = TRIO_FALSE; /* NaN has no sign */    return TRIO_FP_NAN;  case FP_POS_INF:    *is_negative = TRIO_FALSE;    return TRIO_FP_INFINITE;  case FP_NEG_INF:    *is_negative = TRIO_TRUE;    return TRIO_FP_INFINITE;  case FP_POS_DENORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_SUBNORMAL;  case FP_NEG_DENORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_SUBNORMAL;  case FP_POS_ZERO:    *is_negative = TRIO_FALSE;    return TRIO_FP_ZERO;  case FP_NEG_ZERO:    *is_negative = TRIO_TRUE;    return TRIO_FP_ZERO;  case FP_POS_NORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_NORMAL;  case FP_NEG_NORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_NORMAL;  default:    *is_negative = (number < 0.0);    return TRIO_FP_NORMAL;  }}#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)TRIO_PRIVATE_NAN intms_fpclassify_and_signbitTRIO_ARGS2((number, is_negative),	  double number,	  int *is_negative){  int result;# if defined(TRIO_COMPILER_BORLAND)  /*   * The floating-point precision may be changed by the Borland _fpclass()   * function, so we have to save and restore the floating-point control mask.   */  unsigned int mask;  /* Remember the old mask */  mask = _control87(0, 0);# endif    switch (_fpclass(number)) {  case _FPCLASS_QNAN:  case _FPCLASS_SNAN:    *is_negative = TRIO_FALSE; /* NaN has no sign */    result = TRIO_FP_NAN;    break;  case _FPCLASS_PINF:    *is_negative = TRIO_FALSE;    result = TRIO_FP_INFINITE;    break;  case _FPCLASS_NINF:    *is_negative = TRIO_TRUE;    result = TRIO_FP_INFINITE;    break;  case _FPCLASS_PD:    *is_negative = TRIO_FALSE;    result = TRIO_FP_SUBNORMAL;    break;  case _FPCLASS_ND:    *is_negative = TRIO_TRUE;    result = TRIO_FP_SUBNORMAL;    break;  case _FPCLASS_PZ:    *is_negative = TRIO_FALSE;    result = TRIO_FP_ZERO;    break;  case _FPCLASS_NZ:    *is_negative = TRIO_TRUE;    result = TRIO_FP_ZERO;    break;  case _FPCLASS_PN:    *is_negative = TRIO_FALSE;    result = TRIO_FP_NORMAL;    break;  case _FPCLASS_NN:    *is_negative = TRIO_TRUE;    result = TRIO_FP_NORMAL;    break;  default:    *is_negative = (number < 0.0);    result = TRIO_FP_NORMAL;    break;  }  # if defined(TRIO_COMPILER_BORLAND)  /* Restore the old precision */  (void)_control87(mask, MCW_PC);# endif    return result;}#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)TRIO_PRIVATE_NAN TRIO_INLINE inthp_fpclassify_and_signbitTRIO_ARGS2((number, is_negative),	  double number,	  int *is_negative){  /*   * HP-UX 9.x and 10.x have an fpclassify() function, that is different   * from the C99 fpclassify() macro supported on HP-UX 11.x.   */  switch (fpclassify(number)) {  case FP_QNAN:  case FP_SNAN:    *is_negative = TRIO_FALSE; /* NaN has no sign */    return TRIO_FP_NAN;  case FP_PLUS_INF:    *is_negative = TRIO_FALSE;    return TRIO_FP_INFINITE;  case FP_MINUS_INF:    *is_negative = TRIO_TRUE;    return TRIO_FP_INFINITE;  case FP_PLUS_DENORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_SUBNORMAL;  case FP_MINUS_DENORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_SUBNORMAL;  case FP_PLUS_ZERO:    *is_negative = TRIO_FALSE;    return TRIO_FP_ZERO;  case FP_MINUS_ZERO:    *is_negative = TRIO_TRUE;    return TRIO_FP_ZERO;  case FP_PLUS_NORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_NORMAL;  case FP_MINUS_NORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_NORMAL;  default:    *is_negative = (number < 0.0);    return TRIO_FP_NORMAL;  }}#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)TRIO_PRIVATE_NAN TRIO_INLINE intxlc_fpclassify_and_signbitTRIO_ARGS2((number, is_negative),	  double number,	  int *is_negative){  /*   * AIX has class() for C, and _class() for C++   */# if defined(__cplusplus)#  define AIX_CLASS(n) _class(n)# else#  define AIX_CLASS(n) class(n)# endif  switch (AIX_CLASS(number)) {  case FP_QNAN:  case FP_SNAN:    *is_negative = TRIO_FALSE; /* NaN has no sign */    return TRIO_FP_NAN;  case FP_PLUS_INF:    *is_negative = TRIO_FALSE;    return TRIO_FP_INFINITE;  case FP_MINUS_INF:    *is_negative = TRIO_TRUE;    return TRIO_FP_INFINITE;  case FP_PLUS_DENORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_SUBNORMAL;  case FP_MINUS_DENORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_SUBNORMAL;  case FP_PLUS_ZERO:    *is_negative = TRIO_FALSE;    return TRIO_FP_ZERO;  case FP_MINUS_ZERO:    *is_negative = TRIO_TRUE;    return TRIO_FP_ZERO;  case FP_PLUS_NORM:    *is_negative = TRIO_FALSE;    return TRIO_FP_NORMAL;  case FP_MINUS_NORM:    *is_negative = TRIO_TRUE;    return TRIO_FP_NORMAL;  default:    *is_negative = (number < 0.0);    return TRIO_FP_NORMAL;  }}#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */#if defined(TRIO_FUNC_INTERNAL_ISNAN)TRIO_PRIVATE_NAN TRIO_INLINE intinternal_isnanTRIO_ARGS1((number),	   double number){# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)  /*   * XPG3 defines isnan() as a function.   */  return isnan(number);# endif  # if defined(TRIO_INTERNAL_ISNAN_IEEE_754)  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -