Peano 4
Loading...
Searching...
No Matches
CompressedFloatingPointNumbers.cpp
Go to the documentation of this file.
2#include "tarch/Assertions.h"
4#include "tarch/la/Scalar.h"
5
6#include <bitset>
7
8
10 const double values[],
11 int count,
12 double maxError
13) {
14 assertion(count>0);
15
16 int result = 0;
17 for (int i=0; i<count; i++) {
18 result = std::max(result, findMostAgressiveCompression(values[i],maxError));
19 }
20 assertion(result>0);
21 return result;
22}
23
24
25#if defined(CompilerICC)
27#elif defined(CompilerCLANG)
29#else
31#endif
32 double value,
33 double maxError
34) {
35 if (std::abs(value)<maxError) {
36 return 0;
37 }
38
39 assertion(value==value);
40 assertion1( sizeof(long int)*8>=64, sizeof(long int) );
41 assertion(maxError>=0.0);
42
43 // We may not use 7 though we use seven out of eight bits for the first byte.
44 // If we shift by seven, we can end up with the highest byte set for
45 // 0.0155759, e.g.
46 int shiftExponent = 6;
47
48 const long int sign = value < 0.0 ? -1 : 1;
49
50 if (sign<0) {
51 value = -value;
52 }
53
54 int integerExponent;
55 const double significand = std::frexp(value , &integerExponent);
56
57 int usedBytes = 0;
58 double error = std::numeric_limits<double>::max();
59 while (
60 usedBytes<6
61 &&
62 error > maxError
63 ) {
64 usedBytes++;
65
66 const double shiftMantissa = std::pow( 2.0,shiftExponent );
67
68 int exponent = integerExponent-shiftExponent;
69 long int mantissa = static_cast<long int>( std::round(significand*shiftMantissa) );
70
71 error = std::abs( std::ldexp(mantissa,exponent) - value );
72
73 shiftExponent+=8;
74 }
75
76 assertion(usedBytes>=1);
77 assertion(usedBytes<=7);
78
79 return usedBytes;
80}
81
82
83
84#ifdef CompilerICC
86#elif defined(CompilerCLANG)
88#else
90#endif
91 double value,
92 char exponent[8],
93 long int mantissa[8],
94 double error[8]
95) {
96 assertion(value==value);
97 assertion1( sizeof(long int)*8>=64, sizeof(long int) );
98
99 // We may not use 7 though we use seven out of eight bits for the first byte.
100 // If we shift by seven, we can end up with the highest byte set for
101 // 0.0155759, e.g.
102 int shiftExponent = 6;
103
104 const long int sign = value < 0.0 ? -1 : 1;
105
106 if (sign<0) {
107 value = -value;
108 }
109
110 int integerExponent;
111 const double significand = std::frexp(value , &integerExponent);
112
113 for (int i=0; i<8; i++) {
114 const double shiftMantissa = std::pow( 2.0,shiftExponent );
115
116 if (integerExponent-shiftExponent >= std::numeric_limits<char>::min() ) {
117 exponent[i] = static_cast<char>( integerExponent-shiftExponent );
118 mantissa[i] = static_cast<long int>( std::round(significand*shiftMantissa) );
119 }
120 else {
121 exponent[i] = 0;
122 mantissa[i] = 0;
123 }
124 error[i] = std::abs( std::ldexp(mantissa[i],exponent[i]) - value );
125
126 assertion5( mantissa[i]>=0, value, mantissa[i], exponent[i], error[i], sign );
127
128 std::bitset<64>* mantissaAsBitset = reinterpret_cast<std::bitset<64>*>( &(mantissa[i]) );
129
130 #ifdef Asserts
131 for (int j=(i+1)*8-1; j<64; j++) {
133 !(*mantissaAsBitset)[j],
134 *mantissaAsBitset, value, static_cast<int>( exponent[i] ), mantissa[i], error[i], i, j, significand, integerExponent
135 );
136 }
137 #endif
138
139 if (sign<0) {
140 assertion ( (*mantissaAsBitset)[ (i+1)*8-1 ]==false );
141 mantissaAsBitset->flip( (i+1)*8-1 );
142 }
143
144 shiftExponent+=8;
145 }
146}
147
148
149#ifdef CompilerICC
151#elif defined(CompilerCLANG)
153#else
155#endif
156 double value,
157 char& exponent,
158 long int& mantissa,
159 int bytesForMantissa
160) {
161 assertion(value==value);
162 assertion1( sizeof(long int)*8>=64, sizeof(long int) );
163
164 // We may not use 7 though we use seven out of eight bits for the first byte.
165 // If we shift by seven, we can end up with the highest byte set for
166 // 0.0155759, e.g.
167 int shiftExponent = 6 + (bytesForMantissa-1)*8;
168
169 const long int sign = value < 0.0 ? -1 : 1;
170
171 if (sign<0) {
172 value = -value;
173 }
174
175 int integerExponent;
176 const double significand = std::frexp(value , &integerExponent);
177
178 int exponentAsInteger = integerExponent-shiftExponent;
179
180 if (exponentAsInteger <= std::numeric_limits<char>::min()) {
181 exponent = 0;
182 mantissa = 0;
183 }
184 else {
185 exponent = static_cast<char>( exponentAsInteger );
186
187 const double shiftMantissa = std::pow( 2.0,shiftExponent );
188 mantissa = static_cast<long int>( std::round(significand*shiftMantissa) );
189
190 assertion4( mantissa>=0, value, mantissa, exponent, sign );
191
192 std::bitset<64>* mantissaAsBitset = reinterpret_cast<std::bitset<64>*>( &(mantissa) );
193
194 if (sign<0) {
195 assertion ( (*mantissaAsBitset)[ (bytesForMantissa)*8-1 ]==false );
196 mantissaAsBitset->flip( (bytesForMantissa)*8-1 );
197 }
198 }
199}
200
201
202
204 double value,
205 char exponent[4],
206 int mantissa[4],
207 double error[4]
208) {
209 assertion(value==value);
210 assertion1( sizeof(int)*8>=32, sizeof(int) );
211
212 // We may not use 7 though we use seven out of eight bits for the first byte.
213 // If we shift by seven, we can end up with the highest byte set for
214 // 0.0155759, e.g.
215 int shiftExponent = 6;
216
217 const long int sign = value < 0.0 ? -1 : 1;
218
219 if (sign<0) {
220 value = -value;
221 }
222
223 int integerExponent;
224 const double significand = std::frexp(value , &integerExponent);
225
226 for (int i=0; i<4; i++) {
227 const double shiftMantissa = std::pow( 2.0,shiftExponent );
228
229 if (integerExponent-shiftExponent >= std::numeric_limits<char>::min() ) {
230 exponent[i] = static_cast<char>( integerExponent-shiftExponent );
231 mantissa[i] = static_cast<int>( std::round(significand*shiftMantissa) );
232 }
233 else {
234 exponent[i] = 0;
235 mantissa[i] = 0;
236 }
237 error[i] = std::abs( std::ldexp(mantissa[i],exponent[i]) - value );
238
239 assertion5( mantissa[i]>=0, value, mantissa[i], exponent[i], error[i], sign );
240
241 std::bitset< sizeof(int)*8 >* mantissaAsBitset = reinterpret_cast<std::bitset< sizeof(int)*8 >*>( &(mantissa[i]) );
242
243 #ifdef Asserts
244 for (int j=(i+1)*8-1; j<static_cast<int>( sizeof(int) )*8; j++) {
246 !(*mantissaAsBitset)[j],
247 *mantissaAsBitset, value, static_cast<int>( exponent[i] ), mantissa[i], error[i], i, j, significand, integerExponent
248 );
249 }
250 #endif
251
252 if (sign<0) {
253 assertion ( (*mantissaAsBitset)[ (i+1)*8-1 ]==false );
254 mantissaAsBitset->flip( (i+1)*8-1 );
255 }
256
257 shiftExponent+=8;
258 }
259}
260
261
263 char exponent,
264 long int mantissa,
265 int bytesUsed
266) {
267 assertion( bytesUsed>=1 );
268
269 std::bitset<64>* mantissaAsBitset = reinterpret_cast<std::bitset<64>*>( &mantissa );
270
271 if ( (*mantissaAsBitset)[ bytesUsed*8-1 ] ) {
272 mantissaAsBitset->flip( bytesUsed*8-1 );
273 mantissa = -mantissa;
274 }
275
276 const double doubleMantissa = mantissa;
277 const int intExponent = exponent;
278
279 return std::ldexp(doubleMantissa,intExponent);
280}
281
282
#define assertion4(expr, param0, param1, param2, param3)
#define assertion1(expr, param)
#define assertion9(expr, param0, param1, param2, param3, param4, param5, param6, param7, param8)
#define assertion(expr)
#define assertion5(expr, param0, param1, param2, param3, param4)
int __attribute__((optimize("O0"))) toolbox
And from this we can write down f$ nabla phi_i nabla phi_i dx but since we are constructing matrix let s investigate the f$ our matrix elements will nabla phi_i dx f By this will be a sparse as these basis functions are chosen to not overlap with each other almost everywhere In other they have only local support We can read off the right hand side values
And from this we can write down f$ nabla phi_i nabla phi_i dx but since we are constructing matrix let s investigate the f$ j
#define CompilerCLANG
Definition LinuxAMD.h:6
int i
Definition makeIC.py:51
int sign(double value, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
void decompose(const double &value, char &exponent, T &mantissa)
Takes a double and returns the exponent and the mantissa.
double compose(const char &exponent, const T &mantissa)
int findMostAgressiveCompression(double value, double maxAbsoluteError)
Analyses the handed data and determines the most aggressive compression.
void decomposeIntoFourVariants(double value, char exponent[4], int mantissa[4], double error[4])
void decomposeIntoEightVariants(double value, char exponent[8], long int mantissa[8], double error[8])
Decompose floating point value.