Logo ROOT   6.07/09
Reference Guide
vdtcore_common.h
Go to the documentation of this file.
1 /*
2  * vdtcore_common.h
3  * Common functions for the vdt routines.
4  * The basic idea is to exploit Pade polynomials.
5  * A lot of ideas were inspired by the cephes math library (by Stephen L. Moshier
6  * moshier@na-net.ornl.gov) as well as actual code for the exp, log, sin, cos,
7  * tan, asin, acos and atan functions. The Cephes library can be found here:
8  * http://www.netlib.org/cephes/
9  *
10  * Created on: Jun 23, 2012
11  * Author: Danilo Piparo, Thomas Hauth, Vincenzo Innocente
12  */
13 
14 /*
15  * VDT is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU Lesser Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU Lesser Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser Public License
26  * along with this program. If not, see <http://www.gnu.org/licenses/>.
27  */
28 
29 #ifndef VDTCOMMON_H_
30 #define VDTCOMMON_H_
31 
32 #include "inttypes.h"
33 #include <cmath>
34 
35 namespace vdt{
36 
37 namespace details{
38 
39 // Constants
40 const double TWOPI = 2.*M_PI;
41 const double PI = M_PI;
42 const double PIO2 = M_PI_2;
43 const double PIO4 = M_PI_4;
44 const double ONEOPIO4 = 4./M_PI;
45 
46 const float TWOPIF = 2.*M_PI;
47 const float PIF = M_PI;
48 const float PIO2F = M_PI_2;
49 const float PIO4F = M_PI_4;
50 const float ONEOPIO4F = 4./M_PI;
51 
52 const double MOREBITS = 6.123233995736765886130E-17;
53 
54 
55 const float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
56 
57 //------------------------------------------------------------------------------
58 
59 /// Used to switch between different type of interpretations of the data (64 bits)
60 union ieee754{
61  ieee754 () {};
62  ieee754 (double thed) {d=thed;};
63  ieee754 (uint64_t thell) {ll=thell;};
64  ieee754 (float thef) {f[0]=thef;};
65  ieee754 (uint32_t thei) {i[0]=thei;};
66  double d;
67  float f[2];
68  uint32_t i[2];
69  uint64_t ll;
70  uint16_t s[4];
71 };
72 
73 //------------------------------------------------------------------------------
74 
75 /// Converts an unsigned long long to a double
76 inline double uint642dp(uint64_t ll) {
77  ieee754 tmp;
78  tmp.ll=ll;
79  return tmp.d;
80 }
81 
82 //------------------------------------------------------------------------------
83 
84 /// Converts a double to an unsigned long long
85 inline uint64_t dp2uint64(double x) {
86  ieee754 tmp;
87  tmp.d=x;
88  return tmp.ll;
89 }
90 
91 //------------------------------------------------------------------------------
92 /// Makes an AND of a double and a unsigned long long
93 inline double dpANDuint64(const double x, const uint64_t i ){
94  return uint642dp(dp2uint64(x) & i);
95 }
96 //------------------------------------------------------------------------------
97 /// Makes an OR of a double and a unsigned long long
98 inline double dpORuint64(const double x, const uint64_t i ){
99  return uint642dp(dp2uint64(x) | i);
100 }
101 
102 /// Makes a XOR of a double and a unsigned long long
103 inline double dpXORuint64(const double x, const uint64_t i ){
104  return uint642dp(dp2uint64(x) ^ i);
105 }
106 
107 //------------------------------------------------------------------------------
108 inline uint64_t getSignMask(const double x){
109  const uint64_t mask=0x8000000000000000ULL;
110  return dp2uint64(x) & mask;
111 }
112 
113 //------------------------------------------------------------------------------
114 /// Converts an int to a float
115 inline float uint322sp(int x) {
116  ieee754 tmp;
117  tmp.i[0]=x;
118  return tmp.f[0];
119  }
120 
121 //------------------------------------------------------------------------------
122 /// Converts a float to an int
123 inline uint32_t sp2uint32(float x) {
124  ieee754 tmp;
125  tmp.f[0]=x;
126  return tmp.i[0];
127  }
128 
129 //------------------------------------------------------------------------------
130 /// Makes an AND of a float and a unsigned long
131 inline float spANDuint32(const float x, const uint32_t i ){
132  return uint322sp(sp2uint32(x) & i);
133 }
134 //------------------------------------------------------------------------------
135 /// Makes an OR of a float and a unsigned long
136 inline float spORuint32(const float x, const uint32_t i ){
137  return uint322sp(sp2uint32(x) | i);
138 }
139 
140 //------------------------------------------------------------------------------
141 /// Makes an OR of a float and a unsigned long
142 inline float spXORuint32(const float x, const uint32_t i ){
143  return uint322sp(sp2uint32(x) ^ i);
144 }
145 //------------------------------------------------------------------------------
146 /// Get the sign mask
147 inline uint32_t getSignMask(const float x){
148  const uint32_t mask=0x80000000;
149  return sp2uint32(x) & mask;
150 }
151 
152 //------------------------------------------------------------------------------
153 /// Like frexp but vectorising and the exponent is a double.
154 inline double getMantExponent(const double x, double & fe){
155 
156  uint64_t n = dp2uint64(x);
157 
158  // Shift to the right up to the beginning of the exponent.
159  // Then with a mask, cut off the sign bit
160  uint64_t le = (n >> 52);
161 
162  // chop the head of the number: an int contains more than 11 bits (32)
163  int32_t e = le; // This is important since sums on uint64_t do not vectorise
164  fe = e-1023 ;
165 
166  // This puts to 11 zeroes the exponent
167  n &=0x800FFFFFFFFFFFFFULL;
168  // build a mask which is 0.5, i.e. an exponent equal to 1022
169  // which means *2, see the above +1.
170  const uint64_t p05 = 0x3FE0000000000000ULL; //dp2uint64(0.5);
171  n |= p05;
172 
173  return uint642dp(n);
174 }
175 
176 //------------------------------------------------------------------------------
177 /// Like frexp but vectorising and the exponent is a float.
178 inline float getMantExponentf(const float x, float & fe){
179 
180  uint32_t n = sp2uint32(x);
181  int32_t e = (n >> 23)-127;
182  fe = e;
183 
184  // fractional part
185  const uint32_t p05f = 0x3f000000; // //sp2uint32(0.5);
186  n &= 0x807fffff;// ~0x7f800000;
187  n |= p05f;
188 
189  return uint322sp(n);
190 
191 }
192 
193 //------------------------------------------------------------------------------
194 /// Converts a fp to an int
195 inline uint32_t fp2uint(float x) {
196  return sp2uint32(x);
197  }
198 /// Converts a fp to an int
199 inline uint64_t fp2uint(double x) {
200  return dp2uint64(x);
201  }
202 /// Converts an int to fp
203 inline float int2fp(uint32_t i) {
204  return uint322sp(i);
205  }
206 /// Converts an int to fp
207 inline double int2fp(uint64_t i) {
208  return uint642dp(i);
209  }
210 
211 //------------------------------------------------------------------------------
212 /**
213  * A vectorisable floor implementation, not only triggered by fast-math.
214  * These functions do not distinguish between -0.0 and 0.0, so are not IEC6509
215  * compliant for argument -0.0
216 **/
217 inline double fpfloor(const double x){
218  // no problem since exp is defined between -708 and 708. Int is enough for it!
219  int32_t ret = int32_t (x);
220  ret-=(sp2uint32(x)>>31);
221  return ret;
222 
223 }
224 //------------------------------------------------------------------------------
225 /**
226  * A vectorisable floor implementation, not only triggered by fast-math.
227  * These functions do not distinguish between -0.0 and 0.0, so are not IEC6509
228  * compliant for argument -0.0
229 **/
230 inline float fpfloor(const float x){
231  int32_t ret = int32_t (x);
232  ret-=(sp2uint32(x)>>31);
233  return ret;
234 
235 }
236 
237 //------------------------------------------------------------------------------
238 
239 
240 
241 
242 }
243 
244 } // end of namespace vdt
245 
246 #endif /* VDTCOMMON_H_ */
ieee754(uint32_t thei)
float uint322sp(int x)
Converts an int to a float.
const float ONEOPIO4F
const double PIO2
uint32_t sp2uint32(float x)
Converts a float to an int.
const double TWOPI
float int2fp(uint32_t i)
Converts an int to fp.
const float MAXNUMF
const float PIO4F
Double_t x[n]
Definition: legend1.C:17
float getMantExponentf(const float x, float &fe)
Like frexp but vectorising and the exponent is a float.
double dpXORuint64(const double x, const uint64_t i)
Makes a XOR of a double and a unsigned long long.
#define M_PI_2
Definition: Math.h:42
double fpfloor(const double x)
A vectorisable floor implementation, not only triggered by fast-math.
uint64_t getSignMask(const double x)
const float PIO2F
const double PIO4
double dpANDuint64(const double x, const uint64_t i)
Makes an AND of a double and a unsigned long long.
#define M_PI
Definition: Rotated.cxx:105
uint64_t dp2uint64(double x)
Converts a double to an unsigned long long.
const double ONEOPIO4
const double MOREBITS
double uint642dp(uint64_t ll)
Converts an unsigned long long to a double.
const float TWOPIF
#define M_PI_4
Definition: Math.h:46
ieee754(uint64_t thell)
uint32_t fp2uint(float x)
Converts a fp to an int.
float spANDuint32(const float x, const uint32_t i)
Makes an AND of a float and a unsigned long.
const double PI
float spXORuint32(const float x, const uint32_t i)
Makes an OR of a float and a unsigned long.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Used to switch between different type of interpretations of the data (64 bits)
Definition: asin.h:32
float spORuint32(const float x, const uint32_t i)
Makes an OR of a float and a unsigned long.
double dpORuint64(const double x, const uint64_t i)
Makes an OR of a double and a unsigned long long.
const float PIF
const Int_t n
Definition: legend1.C:16
double getMantExponent(const double x, double &fe)
Like frexp but vectorising and the exponent is a double.