xorp

fp64.h

00001 /* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002  * vim:set sts=4 ts=8: */
00003 
00004 /*
00005  * Copyright (c) 2001-2011 XORP, Inc and Others
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU Lesser General Public License, Version
00009  * 2.1, June 1999 as published by the Free Software Foundation.
00010  * Redistribution and/or modification of this program under the terms of
00011  * any other version of the GNU Lesser General Public License is not
00012  * permitted.
00013  *
00014  * This program is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00017  * see the GNU Lesser General Public License, Version 2.1, a copy of
00018  * which can be found in the XORP LICENSE.lgpl file.
00019  *
00020  * XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00021  * http://xorp.net
00022  */
00023 
00024 #ifndef __LIBXIPC_FP64_H__
00025 #define __LIBXIPC_FP64_H__
00026 
00027 #include <stdint.h>
00028 #include <float.h>
00029 
00030 /* This header chooses a native real type (float, double, long double)
00031    which best matches the IEEE754 binary64 capabilities. */
00032 
00033 
00034 
00035 /* These are the target characteristics of various IEEE754 types,
00036    expressed in terms that make them comparable to the native real
00037    types. */
00038 
00039 /* TODO: We only need the 64-bit details; the others could be in their
00040    own header.  */
00041 
00042 #define XORP_IEEE754_BIN16_MANT_DIG 11
00043 #define XORP_IEEE754_BIN16_MAX_EXP 16
00044 #define XORP_IEEE754_BIN16_MIN_EXP -13
00045 
00046 #define XORP_IEEE754_BIN32_MANT_DIG 24
00047 #define XORP_IEEE754_BIN32_MAX_EXP 128
00048 #define XORP_IEEE754_BIN32_MIN_EXP -125
00049 
00050 #define XORP_IEEE754_BIN64_MANT_DIG 53
00051 #define XORP_IEEE754_BIN64_MAX_EXP 1024
00052 #define XORP_IEEE754_BIN64_MIN_EXP -1021
00053 
00054 #define XORP_IEEE754_BIN128_MANT_DIG 113
00055 #define XORP_IEEE754_BIN128_MAX_EXP 16384
00056 #define XORP_IEEE754_BIN128_MIN_EXP -16381
00057 
00058 
00059 /* TODO: These ratios and test macros are not binary64-specific.  If
00060    other types were to be supported, these macros should be factored
00061    out. */
00062 
00063 /* These are 100000*log2(FLT_RADIX) for various possible FLT_RADIX
00064    values.  In comparing the capabilities of float, double and long
00065    double with binary64, we need to account for the slim possibility
00066    that our native base is not 2, while binary64's base is 2. */
00067 
00068 #define XORP_IEEE754_RADIX_RATIO_2  1000000
00069 #define XORP_IEEE754_RADIX_RATIO_3  1584963
00070 #define XORP_IEEE754_RADIX_RATIO_4  2000000
00071 #define XORP_IEEE754_RADIX_RATIO_5  2321928
00072 #define XORP_IEEE754_RADIX_RATIO_6  2584963
00073 #define XORP_IEEE754_RADIX_RATIO_7  2807354
00074 #define XORP_IEEE754_RADIX_RATIO_8  3000000
00075 #define XORP_IEEE754_RADIX_RATIO_9  3169925
00076 #define XORP_IEEE754_RADIX_RATIO_10 3321928
00077 
00078 #define XORP_IEEE754_RADIX_RATIO_N(B) (XORP_IEEE754_RADIX_RATIO_ ## B)
00079 #define XORP_IEEE754_RADIX_RATIO(B) (XORP_IEEE754_RADIX_RATIO_N(B))
00080 
00081 
00082 /* These preprocessor-safe macros test various native types'
00083    characteristics against IEEE754 types'. */
00084 
00085 #define XORP_IEEE754_TEST_MANT_DIG(T,W) \
00086     ( T ## _MANT_DIG * XORP_IEEE754_RADIX_RATIO(FLT_RADIX) >=       \
00087       XORP_IEEE754_BIN ## W ## _MANT_DIG * XORP_IEEE754_RADIX_RATIO_2 )
00088 
00089 #define XORP_IEEE754_TEST_MAX_EXP(T,W) \
00090     ( T ## _MAX_EXP * XORP_IEEE754_RADIX_RATIO(FLT_RADIX) >=        \
00091       XORP_IEEE754_BIN ## W ## _MAX_EXP * XORP_IEEE754_RADIX_RATIO_2 )
00092 
00093 #define XORP_IEEE754_TEST_MIN_EXP(T,W) \
00094     ( T ## _MIN_EXP * XORP_IEEE754_RADIX_RATIO(FLT_RADIX) <=        \
00095       XORP_IEEE754_BIN ## W ## _MIN_EXP * XORP_IEEE754_RADIX_RATIO_2)
00096 
00097 #define XORP_IEEE754_TEST(T,W)      \
00098     ( XORP_IEEE754_TEST_MANT_DIG(T,W) && \
00099       XORP_IEEE754_TEST_MAX_EXP(T,W) &&  \
00100       XORP_IEEE754_TEST_MIN_EXP(T,W) )
00101 
00102 /* Now we choose a native type to fulfil binary64. */
00103 
00104 #if XORP_IEEE754_TEST(DBL,64)
00105 /* double is sufficient, and is probably the optimal FP type used by
00106    this system. */
00107 #define XORP_IEEE754_BIN64_DBL 1
00108 #else
00109 /* We'll have to use long double, and hope that it is adequate.  What
00110    other choice do we have? */
00111 #define XORP_IEEE754_BIN64_LDBL 1
00112 #endif
00113 
00114 
00115 /* Declare a type alias according to what we've chosen.  Also define
00116    some macros (like those in <inttypes.h>) to print and scan the
00117    type. */
00118 
00119 #if XORP_IEEE754_BIN64_FLT
00120 typedef float fp64_t;
00121 #define XORP_PRIaFP64 "a"
00122 #define XORP_PRIeFP64 "e"
00123 #define XORP_PRIfFP64 "f"
00124 #define XORP_PRIgFP64 "g"
00125 #define XORP_PRIAFP64 "A"
00126 #define XORP_PRIEFP64 "E"
00127 #define XORP_PRIFFP64 "F"
00128 #define XORP_PRIGFP64 "G"
00129 #define XORP_SCNaFP64 "a"
00130 #define XORP_SCNeFP64 "e"
00131 #define XORP_SCNfFP64 "f"
00132 #define XORP_SCNgFP64 "g"
00133 #if __STDC_VERSION__ >= 199901L
00134 #define XORP_FP64(F) F ## f
00135 #define XORP_FP64UC(FN) FN ## F
00136 #else
00137 #define XORP_FP64(F) F
00138 #define XORP_FP64UC(FN) FN
00139 #endif
00140 #define XORP_FP64_DIG FLT_FP64_DIG
00141 #define XORP_FP64_EPSILON FLT_FP64_EPSILON
00142 #define XORP_FP64_MANT_DIG FLT_FP64_MANT_DIG
00143 #define XORP_FP64_MAX FLT_FP64_MAX
00144 #define XORP_FP64_MAX_10_EXP FLT_FP64_MAX_10_EXP
00145 #define XORP_FP64_MAX_EXP FLT_FP64_MAX_EXP
00146 #define XORP_FP64_MIN FLT_FP64_MIN
00147 #define XORP_FP64_MIN_10_EXP FLT_FP64_MIN_10_EXP
00148 #define XORP_FP64_MIN_EXP FLT_FP64_MIN_EXP
00149 #endif
00150 
00151 #if XORP_IEEE754_BIN64_DBL
00152 typedef double fp64_t;
00153 #define XORP_PRIaFP64 "a"
00154 #define XORP_PRIeFP64 "e"
00155 #define XORP_PRIfFP64 "f"
00156 #define XORP_PRIgFP64 "g"
00157 #define XORP_PRIAFP64 "A"
00158 #define XORP_PRIEFP64 "E"
00159 #define XORP_PRIFFP64 "F"
00160 #define XORP_PRIGFP64 "G"
00161 #define XORP_SCNaFP64 "la"
00162 #define XORP_SCNeFP64 "le"
00163 #define XORP_SCNfFP64 "lf"
00164 #define XORP_SCNgFP64 "lg"
00165 #define XORP_FP64(F) F
00166 #define XORP_FP64UC(F) F
00167 #define XORP_FP64_DIG DBL_FP64_DIG
00168 #define XORP_FP64_EPSILON DBL_FP64_EPSILON
00169 #define XORP_FP64_MANT_DIG DBL_FP64_MANT_DIG
00170 #define XORP_FP64_MAX DBL_FP64_MAX
00171 #define XORP_FP64_MAX_10_EXP DBL_FP64_MAX_10_EXP
00172 #define XORP_FP64_MAX_EXP DBL_FP64_MAX_EXP
00173 #define XORP_FP64_MIN DBL_FP64_MIN
00174 #define XORP_FP64_MIN_10_EXP DBL_FP64_MIN_10_EXP
00175 #define XORP_FP64_MIN_EXP DBL_FP64_MIN_EXP
00176 #endif
00177 
00178 #if XORP_IEEE754_BIN64_LDBL
00179 typedef long double fp64_t;
00180 #define XORP_PRIaFP64 "La"
00181 #define XORP_PRIeFP64 "Le"
00182 #define XORP_PRIfFP64 "Lf"
00183 #define XORP_PRIgFP64 "Lg"
00184 #define XORP_PRIAFP64 "LA"
00185 #define XORP_PRIEFP64 "LE"
00186 #define XORP_PRIFFP64 "LF"
00187 #define XORP_PRIGFP64 "LG"
00188 #define XORP_SCNaFP64 "La"
00189 #define XORP_SCNeFP64 "Le"
00190 #define XORP_SCNfFP64 "Lf"
00191 #define XORP_SCNgFP64 "Lg"
00192 #if __STDC_VERSION__ >= 199901L
00193 #define XORP_FP64(F) F ## l
00194 #define XORP_FP64UC(F) F ## L
00195 #else
00196 #define XORP_FP64(F) F
00197 #define XORP_FP64UC(F) F
00198 #endif
00199 #define XORP_FP64_DIG LDBL_FP64_DIG
00200 #define XORP_FP64_EPSILON LDBL_FP64_EPSILON
00201 #define XORP_FP64_MANT_DIG LDBL_FP64_MANT_DIG
00202 #define XORP_FP64_MAX LDBL_FP64_MAX
00203 #define XORP_FP64_MAX_10_EXP LDBL_FP64_MAX_10_EXP
00204 #define XORP_FP64_MAX_EXP LDBL_FP64_MAX_EXP
00205 #define XORP_FP64_MIN LDBL_FP64_MIN
00206 #define XORP_FP64_MIN_10_EXP LDBL_FP64_MIN_10_EXP
00207 #define XORP_FP64_MIN_EXP LDBL_FP64_MIN_EXP
00208 #endif
00209 
00210 
00211 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations