File indexing completed on 2025-06-29 04:09:07
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2004 The University of Toronto * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 0013 // NOTE: only include this from .cpp files 0014 0015 #ifndef MATH_KST_H 0016 #define MATH_KST_H 0017 0018 #include <math.h> 0019 #include <float.h> 0020 #include <stdlib.h> 0021 #include <limits.h> 0022 0023 #ifdef __sun 0024 #include <ieeefp.h> 0025 #endif 0026 0027 #include "kst_export.h" 0028 0029 #ifdef _MSC_VER 0030 inline double pow(float a, double b) { return pow((double)a, b); } 0031 inline double pow(int a, qreal b) { return pow((double)a, (double)b); } 0032 #endif 0033 0034 namespace Kst { 0035 /* 0036 ** For systems without NAN, this is a NAN in IEEE double format. 0037 ** Code from KDE's kjs libarary. 0038 */ 0039 #if !defined(NAN) 0040 #include <qconfig.h> 0041 static double nan__() 0042 { 0043 /* work around some strict alignment requirements 0044 for double variables on some architectures (e.g. PA-RISC) */ 0045 typedef union { unsigned char b[8]; double d; } kjs_double_t; 0046 #if Q_BYTE_ORDER == Q_BIG_ENDIAN 0047 static const kjs_double_t NaN_Bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } }; 0048 #elif defined(arm) 0049 static const kjs_double_t NaN_Bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } }; 0050 #else 0051 static const kjs_double_t NaN_Bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }; 0052 #endif 0053 0054 const double NaN = NaN_Bytes.d; 0055 return NaN; 0056 } 0057 #define NAN (Kst::nan__()) 0058 #endif 0059 0060 #ifndef M_PI 0061 #define M_PI 3.14159265358979323846 0062 #endif 0063 0064 /* 0065 ** Both Solaris and FreeBSD-current do weird things with the 0066 ** isnan() defined in math.h - in particular on FreeBSD it 0067 ** gets #undeffed by the C++ math routines later. Use the 0068 ** std:: version in those cases. 0069 */ 0070 #ifdef isnan 0071 #define KST_ISNAN(a) isnan(a) 0072 #elif defined(__APPLE__) 0073 #define KST_ISNAN(a) (a == NAN ? 1 : 0) 0074 #else 0075 // HUH? Ok let's get rid of the silliness here sometime. 0076 #define KST_ISNAN(a) isnan(a) 0077 #endif 0078 0079 0080 KSTCORE_EXPORT extern const double NOPOINT; 0081 0082 inline int d2i(double x) { 0083 return int(floor(x+0.5)); 0084 } 0085 0086 inline bool samePixel(double x1, double x2) { 0087 //return (int(floor(x1)) == int(floor(x2))); 0088 return (int(x1) == int(x2)); 0089 } 0090 0091 #if defined(__SVR4) && defined(__sun) 0092 inline int isinf(double x) { return x == x && !finite(x); } 0093 #endif 0094 0095 #ifdef Q_CC_MSVC 0096 #ifndef isnan 0097 #define isnan _isnan 0098 #endif 0099 #ifndef finite 0100 #define finite _finite 0101 #endif 0102 #ifndef M_PI 0103 #define M_PI 3.14159265358979323 0104 #endif 0105 #ifndef isinf 0106 #define isinf !_finite 0107 #endif 0108 template<class T> 0109 bool isfinite(T value) { return !isinf(value); } 0110 #endif 0111 0112 #if 0 0113 #define isnan _isnan 0114 #define finite _finite 0115 #ifndef M_PI 0116 #define M_PI 3.14159265358979323 0117 #endif 0118 #define isinf !_finite 0119 #endif 0120 0121 inline double logXLo(double x, double base = 10.0) { 0122 if (base == 10.0) { 0123 return x > 0.0 ? log10(x) : -350.0; 0124 } else { 0125 return x > 0.0 ? log10(x)/log10(base) : -350.0; 0126 } 0127 } 0128 0129 inline double logXHi(double x, double base = 10.0) { 0130 if (base == 10.0) { 0131 return x > 0.0 ? log10(x) : -340.0; 0132 } else { 0133 return x > 0.0 ? log10(x)/log10(base) : -340.0; 0134 } 0135 } 0136 0137 inline double logYLo(double x, double base = 10.0) { 0138 if (base == 10.0) { 0139 return x > 0.0 ? log10(x) : -350.0; 0140 } else { 0141 return x > 0.0 ? log10(x)/log10(base) : -350.0; 0142 } 0143 } 0144 0145 inline double logYHi(double x, double base = 10.0) { 0146 if (base == 10.0) { 0147 return x > 0.0 ? log10(x) : -340.0; 0148 } else { 0149 return x > 0.0 ? log10(x)/log10(base) : -340.0; 0150 } 0151 } 0152 0153 inline double roundDouble (double x) { 0154 #ifdef rint 0155 return rint(x); 0156 #else 0157 int i = (int) x; 0158 if (x >= 0.0) { 0159 return ((x-i) >= 0.5) ? (i + 1) : (i); 0160 } else { 0161 return (-x+i >= 0.5) ? (i - 1) : (i); 0162 } 0163 #endif 0164 } 0165 } 0166 #endif 0167 0168 // vim: ts=2 sw=2 et