File indexing completed on 2026-09-13 09:10:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 #ifndef G4Log_hh
0058 #define G4Log_hh 1
0059
0060 #ifdef WIN32
0061
0062 # define G4Log std::log
0063
0064 #else
0065
0066 # include "G4Types.hh"
0067 # include "G4IEEE754.hh"
0068 # include <cstdint>
0069 # include <limits>
0070
0071
0072
0073 namespace G4LogConsts
0074 {
0075 const G4double LOG_UPPER_LIMIT = 1e307;
0076 const G4double LOG_LOWER_LIMIT = 0;
0077
0078 const G4double SQRTH = 0.70710678118654752440;
0079 const G4float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
0080
0081 inline G4double get_log_px(const G4double x)
0082 {
0083 const G4double PX1log = 1.01875663804580931796E-4;
0084 const G4double PX2log = 4.97494994976747001425E-1;
0085 const G4double PX3log = 4.70579119878881725854E0;
0086 const G4double PX4log = 1.44989225341610930846E1;
0087 const G4double PX5log = 1.79368678507819816313E1;
0088 const G4double PX6log = 7.70838733755885391666E0;
0089
0090 G4double px = PX1log;
0091 px *= x;
0092 px += PX2log;
0093 px *= x;
0094 px += PX3log;
0095 px *= x;
0096 px += PX4log;
0097 px *= x;
0098 px += PX5log;
0099 px *= x;
0100 px += PX6log;
0101 return px;
0102 }
0103
0104 inline G4double get_log_qx(const G4double x)
0105 {
0106 const G4double QX1log = 1.12873587189167450590E1;
0107 const G4double QX2log = 4.52279145837532221105E1;
0108 const G4double QX3log = 8.29875266912776603211E1;
0109 const G4double QX4log = 7.11544750618563894466E1;
0110 const G4double QX5log = 2.31251620126765340583E1;
0111
0112 G4double qx = x;
0113 qx += QX1log;
0114 qx *= x;
0115 qx += QX2log;
0116 qx *= x;
0117 qx += QX3log;
0118 qx *= x;
0119 qx += QX4log;
0120 qx *= x;
0121 qx += QX5log;
0122 return qx;
0123 }
0124
0125
0126
0127 inline G4double getMantExponent(const G4double x, G4double& fe)
0128 {
0129 uint64_t n = G4IEEE754::dp2uint64(x);
0130
0131
0132
0133 uint64_t le = (n >> 52);
0134
0135
0136 int32_t e =
0137 (int32_t)le;
0138 fe = e - 1023;
0139
0140
0141 n &= 0x800FFFFFFFFFFFFFULL;
0142
0143
0144 const uint64_t p05 = 0x3FE0000000000000ULL;
0145 n |= p05;
0146
0147 return G4IEEE754::uint642dp(n);
0148 }
0149
0150
0151
0152 inline G4float getMantExponentf(const G4float x, G4float& fe)
0153 {
0154 uint32_t n = G4IEEE754::sp2uint32(x);
0155 int32_t e = (n >> 23) - 127;
0156 fe = e;
0157
0158
0159 const uint32_t p05f = 0x3f000000;
0160 n &= 0x807fffff;
0161 n |= p05f;
0162
0163 return G4IEEE754::uint322sp(n);
0164 }
0165 }
0166
0167
0168
0169 inline G4double G4Log(G4double x)
0170 {
0171 const G4double original_x = x;
0172
0173
0174 G4double fe;
0175 x = G4LogConsts::getMantExponent(x, fe);
0176
0177
0178 x > G4LogConsts::SQRTH ? fe += 1. : x += x;
0179 x -= 1.0;
0180
0181
0182 G4double px = G4LogConsts::get_log_px(x);
0183
0184
0185 const G4double x2 = x * x;
0186 px *= x;
0187 px *= x2;
0188
0189 const G4double qx = G4LogConsts::get_log_qx(x);
0190
0191 G4double res = px / qx;
0192
0193 res -= fe * 2.121944400546905827679e-4;
0194 res -= 0.5 * x2;
0195
0196 res = x + res;
0197 res += fe * 0.693359375;
0198
0199 if(original_x > G4LogConsts::LOG_UPPER_LIMIT)
0200 res = std::numeric_limits<G4double>::infinity();
0201 if(original_x < G4LogConsts::LOG_LOWER_LIMIT)
0202 res = -std::numeric_limits<G4double>::quiet_NaN();
0203
0204 return res;
0205 }
0206
0207
0208
0209 namespace G4LogConsts
0210 {
0211 const G4float LOGF_UPPER_LIMIT = MAXNUMF;
0212 const G4float LOGF_LOWER_LIMIT = 0;
0213
0214 const G4float PX1logf = 7.0376836292E-2f;
0215 const G4float PX2logf = -1.1514610310E-1f;
0216 const G4float PX3logf = 1.1676998740E-1f;
0217 const G4float PX4logf = -1.2420140846E-1f;
0218 const G4float PX5logf = 1.4249322787E-1f;
0219 const G4float PX6logf = -1.6668057665E-1f;
0220 const G4float PX7logf = 2.0000714765E-1f;
0221 const G4float PX8logf = -2.4999993993E-1f;
0222 const G4float PX9logf = 3.3333331174E-1f;
0223
0224 inline G4float get_log_poly(const G4float x)
0225 {
0226 G4float y = x * PX1logf;
0227 y += PX2logf;
0228 y *= x;
0229 y += PX3logf;
0230 y *= x;
0231 y += PX4logf;
0232 y *= x;
0233 y += PX5logf;
0234 y *= x;
0235 y += PX6logf;
0236 y *= x;
0237 y += PX7logf;
0238 y *= x;
0239 y += PX8logf;
0240 y *= x;
0241 y += PX9logf;
0242 return y;
0243 }
0244
0245 const G4float SQRTHF = 0.707106781186547524f;
0246 }
0247
0248
0249
0250 inline G4float G4Logf(G4float x)
0251 {
0252 const G4float original_x = x;
0253
0254 G4float fe;
0255 x = G4LogConsts::getMantExponentf(x, fe);
0256
0257 x > G4LogConsts::SQRTHF ? fe += 1.f : x += x;
0258 x -= 1.0f;
0259
0260 const G4float x2 = x * x;
0261
0262 G4float res = G4LogConsts::get_log_poly(x);
0263 res *= x2 * x;
0264
0265 res += -2.12194440e-4f * fe;
0266 res += -0.5f * x2;
0267
0268 res = x + res;
0269
0270 res += 0.693359375f * fe;
0271
0272 if(original_x > G4LogConsts::LOGF_UPPER_LIMIT)
0273 res = std::numeric_limits<G4float>::infinity();
0274 if(original_x < G4LogConsts::LOGF_LOWER_LIMIT)
0275 res = -std::numeric_limits<G4float>::quiet_NaN();
0276
0277 return res;
0278 }
0279
0280 #endif
0281
0282 #endif