Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/NativeInterpreter-0.1/lib/vdt/vdtcore_common.h @ 16269

Last change on this file since 16269 was 16269, checked in by bburlacu, 5 years ago

#2958: Add C++ source code

File size: 7.5 KB
Line 
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 <cinttypes>
33#include <cmath>
34
35namespace vdt{
36
37namespace details{
38
39// Constants
40const double TWOPI = 2.*M_PI;
41const double PI = M_PI;
42const double PIO2 = M_PI_2;
43const double PIO4 = M_PI_4;
44const double ONEOPIO4 = 4./M_PI;
45
46const float TWOPIF = 2.*M_PI;
47const float PIF = M_PI;
48const float PIO2F = M_PI_2;
49const float PIO4F = M_PI_4;
50const float ONEOPIO4F = 4./M_PI;
51
52const double MOREBITS = 6.123233995736765886130E-17;
53
54
55const float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
56
57//------------------------------------------------------------------------------
58
59/// Used to switch between different type of interpretations of the data (64 bits)
60union ieee754{
61  inline ieee754 () {};
62  inline ieee754 (double thed) {d=thed;};
63  inline ieee754 (uint64_t thell) {ll=thell;};
64  inline ieee754 (float thef) {f[0]=thef;};
65  inline 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
76inline 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
85inline 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
93inline 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
98inline 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
103inline double dpXORuint64(const double x, const uint64_t i ){
104  return uint642dp(dp2uint64(x) ^ i);
105}
106
107//------------------------------------------------------------------------------
108inline 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
115inline 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
123inline 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
131inline 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
136inline 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
142inline float spXORuint32(const float x, const uint32_t i ){
143  return uint322sp(sp2uint32(x) ^ i);
144}
145//------------------------------------------------------------------------------
146/// Get the sign mask
147inline 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.
154inline 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.
178inline 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
195inline uint32_t fp2uint(float x) {
196    return sp2uint32(x);
197  }
198/// Converts a fp to an int
199inline uint64_t fp2uint(double x) {
200    return dp2uint64(x);
201  }
202/// Converts an int to fp
203inline float int2fp(uint32_t i) {
204    return uint322sp(i);
205  }
206/// Converts an int to fp
207inline 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**/
217inline 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**/
230inline 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} // end of namespace vdt
242
243#endif /* VDTCOMMON_H_ */
Note: See TracBrowser for help on using the repository browser.