1 /* 2 * Copyright (C) 2003-2006 Manuel Novoa III 3 * 4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. 5 */ 6 /* Define a maximal floating point type, and the associated constants 7 * that are defined for the floating point types in float.h. 8 * 9 * This is to support archs that are missing long double, or even double. 10 */ 11 12 #ifndef _UCLIBC_FPMAX_H 13 #define _UCLIBC_FPMAX_H 14 15 #include <features.h> 16 #include <float.h> 17 18 #ifdef __UCLIBC_HAS_FLOATS__ 19 20 #if defined(LDBL_MANT_DIG) 21 22 typedef long double __fpmax_t; 23 #define FPMAX_TYPE 3 24 25 #define FPMAX_MANT_DIG LDBL_MANT_DIG 26 #define FPMAX_DIG LDBL_DIG 27 #define FPMAX_EPSILON LDBL_EPSILON 28 #define FPMAX_MIN_EXP LDBL_MIN_EXP 29 #define FPMAX_MIN LDBL_MIN 30 #define FPMAX_MIN_10_EXP LDBL_MIN_10_EXP 31 #define FPMAX_MAX_EXP LDBL_MAX_EXP 32 #define FPMAX_MAX LDBL_MAX 33 #define FPMAX_MAX_10_EXP LDBL_MAX_10_EXP 34 35 #elif defined(DBL_MANT_DIG) 36 37 typedef double __fpmax_t; 38 #define FPMAX_TYPE 2 39 40 #define FPMAX_MANT_DIG DBL_MANT_DIG 41 #define FPMAX_DIG DBL_DIG 42 #define FPMAX_EPSILON DBL_EPSILON 43 #define FPMAX_MIN_EXP DBL_MIN_EXP 44 #define FPMAX_MIN DBL_MIN 45 #define FPMAX_MIN_10_EXP DBL_MIN_10_EXP 46 #define FPMAX_MAX_EXP DBL_MAX_EXP 47 #define FPMAX_MAX DBL_MAX 48 #define FPMAX_MAX_10_EXP DBL_MAX_10_EXP 49 50 #elif defined(FLT_MANT_DIG) 51 52 typedef float __fpmax_t; 53 #define FPMAX_TYPE 1 54 55 #define FPMAX_MANT_DIG FLT_MANT_DIG 56 #define FPMAX_DIG FLT_DIG 57 #define FPMAX_EPSILON FLT_EPSILON 58 #define FPMAX_MIN_EXP FLT_MIN_EXP 59 #define FPMAX_MIN FLT_MIN 60 #define FPMAX_MIN_10_EXP FLT_MIN_10_EXP 61 #define FPMAX_MAX_EXP FLT_MAX_EXP 62 #define FPMAX_MAX FLT_MAX 63 #define FPMAX_MAX_10_EXP FLT_MAX_10_EXP 64 65 #else 66 #error unable to determine appropriate type for __fpmax_t! 67 #endif 68 69 #ifndef DECIMAL_DIG 70 71 #ifdef L___strtofpmax 72 /* Emit warning only once. */ 73 #warning DECIMAL_DIG is not defined! If you are using gcc, it may not be defining __STDC_VERSION__ as it should. 74 #endif 75 #if !defined(FLT_RADIX) || (FLT_RADIX != 2) 76 #error unable to compensate for missing DECIMAL_DIG! 77 #endif 78 79 /* ceil (1 + #mantissa * log10 (FLT_RADIX)) */ 80 #define DECIMAL_DIG (1 + (((FPMAX_MANT_DIG * 100) + 331) / 332)) 81 82 #endif /* DECIMAL_DIG */ 83 84 #if defined _LIBC && defined IS_IN_libc 85 extern __fpmax_t __strtofpmax(const char *str, char **endptr, int exp_adjust) attribute_hidden; 86 87 #ifdef __UCLIBC_HAS_XLOCALE__ 88 extern __fpmax_t __strtofpmax_l(const char *str, char **endptr, int exp_adjust, 89 __locale_t locale_arg) attribute_hidden; 90 #endif 91 92 #ifdef __UCLIBC_HAS_WCHAR__ 93 extern __fpmax_t __wcstofpmax(const wchar_t *wcs, wchar_t **endptr, 94 int exp_adjust) attribute_hidden; 95 96 #ifdef __UCLIBC_HAS_XLOCALE__ 97 extern __fpmax_t __wcstofpmax_l(const wchar_t *wcs, wchar_t **endptr, 98 int exp_adjust, __locale_t locale_arg) attribute_hidden; 99 #endif 100 #endif /* __UCLIBC_HAS_WCHAR__ */ 101 #endif /* _LIBC */ 102 103 /* The following checks in an __fpmax_t is either 0 or +/- infinity. 104 * 105 * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! 106 * 107 * This only works if __fpmax_t is the actual maximal floating point type used 108 * in intermediate calculations. Otherwise, excess precision in the 109 * intermediate values can cause the test to fail. 110 * 111 * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! 112 */ 113 114 #define __FPMAX_ZERO_OR_INF_CHECK(x) ((x) == ((x)/4) ) 115 116 #endif /* __UCLIBC_HAS_FLOATS__ */ 117 118 #endif /* _UCLIBC_FPMAX_H */ 119