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