OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libgcc/] [config/] [libbid/] [bid64_round_integral.c] - Blame information for rev 272

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 272 jeremybenn
/* Copyright (C) 2007, 2009  Free Software Foundation, Inc.
2
 
3
This file is part of GCC.
4
 
5
GCC is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free
7
Software Foundation; either version 3, or (at your option) any later
8
version.
9
 
10
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
for more details.
14
 
15
Under Section 7 of GPL version 3, you are granted additional
16
permissions described in the GCC Runtime Library Exception, version
17
3.1, as published by the Free Software Foundation.
18
 
19
You should have received a copy of the GNU General Public License and
20
a copy of the GCC Runtime Library Exception along with this program;
21
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22
<http://www.gnu.org/licenses/>.  */
23
 
24
#include "bid_internal.h"
25
 
26
/*****************************************************************************
27
 *  BID64_round_integral_exact
28
 ****************************************************************************/
29
 
30
#if DECIMAL_CALL_BY_REFERENCE
31
void
32
bid64_round_integral_exact (UINT64 * pres,
33
                            UINT64 *
34
                            px _RND_MODE_PARAM _EXC_FLAGS_PARAM
35
                            _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
36
  UINT64 x = *px;
37
#if !DECIMAL_GLOBAL_ROUNDING
38
  unsigned int rnd_mode = *prnd_mode;
39
#endif
40
#else
41
UINT64
42
bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM
43
                            _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
44
#endif
45
 
46
  UINT64 res = 0xbaddbaddbaddbaddull;
47
  UINT64 x_sign;
48
  int exp;                      // unbiased exponent
49
  // Note: C1 represents the significand (UINT64)
50
  BID_UI64DOUBLE tmp1;
51
  int x_nr_bits;
52
  int q, ind, shift;
53
  UINT64 C1;
54
  // UINT64 res is C* at first - represents up to 16 decimal digits <= 54 bits
55
  UINT128 fstar = { {0x0ull, 0x0ull} };
56
  UINT128 P128;
57
 
58
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
59
 
60
  // check for NaNs and infinities
61
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
62
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
63
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
64
    else
65
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12
66
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
67
      // set invalid flag
68
      *pfpsf |= INVALID_EXCEPTION;
69
      // return quiet (SNaN)
70
      res = x & 0xfdffffffffffffffull;
71
    } else {    // QNaN
72
      res = x;
73
    }
74
    BID_RETURN (res);
75
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
76
    res = x_sign | 0x7800000000000000ull;
77
    BID_RETURN (res);
78
  }
79
  // unpack x
80
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
81
    // if the steering bits are 11 (condition will be 0), then 
82
    // the exponent is G[0:w+1]
83
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
84
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
85
    if (C1 > 9999999999999999ull) {     // non-canonical
86
      C1 = 0;
87
    }
88
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
89
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
90
    C1 = (x & MASK_BINARY_SIG1);
91
  }
92
 
93
  // if x is 0 or non-canonical return 0 preserving the sign bit and 
94
  // the preferred exponent of MAX(Q(x), 0)
95
  if (C1 == 0) {
96
    if (exp < 0)
97
      exp = 0;
98
    res = x_sign | (((UINT64) exp + 398) << 53);
99
    BID_RETURN (res);
100
  }
101
  // x is a finite non-zero number (not 0, non-canonical, or special)
102
 
103
  switch (rnd_mode) {
104
  case ROUNDING_TO_NEAREST:
105
  case ROUNDING_TIES_AWAY:
106
    // return 0 if (exp <= -(p+1))
107
    if (exp <= -17) {
108
      res = x_sign | 0x31c0000000000000ull;
109
      *pfpsf |= INEXACT_EXCEPTION;
110
      BID_RETURN (res);
111
    }
112
    break;
113
  case ROUNDING_DOWN:
114
    // return 0 if (exp <= -p)
115
    if (exp <= -16) {
116
      if (x_sign) {
117
        res = 0xb1c0000000000001ull;
118
      } else {
119
        res = 0x31c0000000000000ull;
120
      }
121
      *pfpsf |= INEXACT_EXCEPTION;
122
      BID_RETURN (res);
123
    }
124
    break;
125
  case ROUNDING_UP:
126
    // return 0 if (exp <= -p)
127
    if (exp <= -16) {
128
      if (x_sign) {
129
        res = 0xb1c0000000000000ull;
130
      } else {
131
        res = 0x31c0000000000001ull;
132
      }
133
      *pfpsf |= INEXACT_EXCEPTION;
134
      BID_RETURN (res);
135
    }
136
    break;
137
  case ROUNDING_TO_ZERO:
138
    // return 0 if (exp <= -p) 
139
    if (exp <= -16) {
140
      res = x_sign | 0x31c0000000000000ull;
141
      *pfpsf |= INEXACT_EXCEPTION;
142
      BID_RETURN (res);
143
    }
144
    break;
145
  }     // end switch ()
146
 
147
  // q = nr. of decimal digits in x (1 <= q <= 54)
148
  //  determine first the nr. of bits in x
149
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
150
    q = 16;
151
  } else {      // if x < 2^53
152
    tmp1.d = (double) C1;       // exact conversion
153
    x_nr_bits =
154
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
155
    q = nr_digits[x_nr_bits - 1].digits;
156
    if (q == 0) {
157
      q = nr_digits[x_nr_bits - 1].digits1;
158
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
159
        q++;
160
    }
161
  }
162
 
163
  if (exp >= 0) {        // -exp <= 0
164
    // the argument is an integer already
165
    res = x;
166
    BID_RETURN (res);
167
  }
168
 
169
  switch (rnd_mode) {
170
  case ROUNDING_TO_NEAREST:
171
    if ((q + exp) >= 0) {        // exp < 0 and 1 <= -exp <= q
172
      // need to shift right -exp digits from the coefficient; exp will be 0
173
      ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
174
      // chop off ind digits from the lower part of C1 
175
      // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
176
      // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
177
      C1 = C1 + midpoint64[ind - 1];
178
      // calculate C* and f*
179
      // C* is actually floor(C*) in this case
180
      // C* and f* need shifting and masking, as shown by
181
      // shiftright128[] and maskhigh128[]
182
      // 1 <= x <= 16
183
      // kx = 10^(-x) = ten2mk64[ind - 1]
184
      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
185
      // the approximation of 10^(-x) was rounded up to 64 bits
186
      __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
187
 
188
      // if (0 < f* < 10^(-x)) then the result is a midpoint
189
      //   if floor(C*) is even then C* = floor(C*) - logical right
190
      //       shift; C* has p decimal digits, correct by Prop. 1)
191
      //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
192
      //       shift; C* has p decimal digits, correct by Pr. 1)
193
      // else  
194
      //   C* = floor(C*) (logical right shift; C has p decimal digits,
195
      //       correct by Property 1)
196
      // n = C* * 10^(e+x)  
197
 
198
      if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
199
        res = P128.w[1];
200
        fstar.w[1] = 0;
201
        fstar.w[0] = P128.w[0];
202
      } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
203
        shift = shiftright128[ind - 1]; // 3 <= shift <= 63
204
        res = (P128.w[1] >> shift);
205
        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
206
        fstar.w[0] = P128.w[0];
207
      }
208
      // if (0 < f* < 10^(-x)) then the result is a midpoint
209
      // since round_to_even, subtract 1 if current result is odd
210
      if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
211
          && (fstar.w[0] < ten2mk64[ind - 1])) {
212
        res--;
213
      }
214
      // determine inexactness of the rounding of C*
215
      // if (0 < f* - 1/2 < 10^(-x)) then
216
      //   the result is exact
217
      // else // if (f* - 1/2 > T*) then
218
      //   the result is inexact
219
      if (ind - 1 <= 2) {
220
        if (fstar.w[0] > 0x8000000000000000ull) {
221
          // f* > 1/2 and the result may be exact
222
          // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
223
          if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
224
            // set the inexact flag
225
            *pfpsf |= INEXACT_EXCEPTION;
226
          }     // else the result is exact
227
        } else {        // the result is inexact; f2* <= 1/2
228
          // set the inexact flag
229
          *pfpsf |= INEXACT_EXCEPTION;
230
        }
231
      } else {  // if 3 <= ind - 1 <= 21
232
        if (fstar.w[1] > onehalf128[ind - 1] ||
233
            (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
234
          // f2* > 1/2 and the result may be exact
235
          // Calculate f2* - 1/2
236
          if (fstar.w[1] > onehalf128[ind - 1]
237
              || fstar.w[0] > ten2mk64[ind - 1]) {
238
            // set the inexact flag
239
            *pfpsf |= INEXACT_EXCEPTION;
240
          }     // else the result is exact
241
        } else {        // the result is inexact; f2* <= 1/2
242
          // set the inexact flag
243
          *pfpsf |= INEXACT_EXCEPTION;
244
        }
245
      }
246
      // set exponent to zero as it was negative before.
247
      res = x_sign | 0x31c0000000000000ull | res;
248
      BID_RETURN (res);
249
    } else {    // if exp < 0 and q + exp < 0
250
      // the result is +0 or -0
251
      res = x_sign | 0x31c0000000000000ull;
252
      *pfpsf |= INEXACT_EXCEPTION;
253
      BID_RETURN (res);
254
    }
255
    break;
256
  case ROUNDING_TIES_AWAY:
257
    if ((q + exp) >= 0) {        // exp < 0 and 1 <= -exp <= q
258
      // need to shift right -exp digits from the coefficient; exp will be 0
259
      ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
260
      // chop off ind digits from the lower part of C1 
261
      // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
262
      // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
263
      C1 = C1 + midpoint64[ind - 1];
264
      // calculate C* and f*
265
      // C* is actually floor(C*) in this case
266
      // C* and f* need shifting and masking, as shown by
267
      // shiftright128[] and maskhigh128[]
268
      // 1 <= x <= 16
269
      // kx = 10^(-x) = ten2mk64[ind - 1]
270
      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
271
      // the approximation of 10^(-x) was rounded up to 64 bits
272
      __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
273
 
274
      // if (0 < f* < 10^(-x)) then the result is a midpoint
275
      //   C* = floor(C*) - logical right shift; C* has p decimal digits, 
276
      //       correct by Prop. 1)
277
      // else
278
      //   C* = floor(C*) (logical right shift; C has p decimal digits,
279
      //       correct by Property 1)
280
      // n = C* * 10^(e+x)
281
 
282
      if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
283
        res = P128.w[1];
284
        fstar.w[1] = 0;
285
        fstar.w[0] = P128.w[0];
286
      } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
287
        shift = shiftright128[ind - 1]; // 3 <= shift <= 63
288
        res = (P128.w[1] >> shift);
289
        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
290
        fstar.w[0] = P128.w[0];
291
      }
292
      // midpoints are already rounded correctly
293
      // determine inexactness of the rounding of C*
294
      // if (0 < f* - 1/2 < 10^(-x)) then
295
      //   the result is exact
296
      // else // if (f* - 1/2 > T*) then
297
      //   the result is inexact
298
      if (ind - 1 <= 2) {
299
        if (fstar.w[0] > 0x8000000000000000ull) {
300
          // f* > 1/2 and the result may be exact 
301
          // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
302
          if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
303
            // set the inexact flag
304
            *pfpsf |= INEXACT_EXCEPTION;
305
          }     // else the result is exact
306
        } else {        // the result is inexact; f2* <= 1/2
307
          // set the inexact flag
308
          *pfpsf |= INEXACT_EXCEPTION;
309
        }
310
      } else {  // if 3 <= ind - 1 <= 21
311
        if (fstar.w[1] > onehalf128[ind - 1] ||
312
            (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
313
          // f2* > 1/2 and the result may be exact
314
          // Calculate f2* - 1/2
315
          if (fstar.w[1] > onehalf128[ind - 1]
316
              || fstar.w[0] > ten2mk64[ind - 1]) {
317
            // set the inexact flag
318
            *pfpsf |= INEXACT_EXCEPTION;
319
          }     // else the result is exact
320
        } else {        // the result is inexact; f2* <= 1/2
321
          // set the inexact flag
322
          *pfpsf |= INEXACT_EXCEPTION;
323
        }
324
      }
325
      // set exponent to zero as it was negative before.
326
      res = x_sign | 0x31c0000000000000ull | res;
327
      BID_RETURN (res);
328
    } else {    // if exp < 0 and q + exp < 0
329
      // the result is +0 or -0
330
      res = x_sign | 0x31c0000000000000ull;
331
      *pfpsf |= INEXACT_EXCEPTION;
332
      BID_RETURN (res);
333
    }
334
    break;
335
  case ROUNDING_DOWN:
336
    if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
337
      // need to shift right -exp digits from the coefficient; exp will be 0
338
      ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
339
      // chop off ind digits from the lower part of C1 
340
      // C1 fits in 64 bits
341
      // calculate C* and f*
342
      // C* is actually floor(C*) in this case
343
      // C* and f* need shifting and masking, as shown by
344
      // shiftright128[] and maskhigh128[]
345
      // 1 <= x <= 16
346
      // kx = 10^(-x) = ten2mk64[ind - 1]
347
      // C* = C1 * 10^(-x)
348
      // the approximation of 10^(-x) was rounded up to 64 bits
349
      __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
350
 
351
      // C* = floor(C*) (logical right shift; C has p decimal digits,
352
      //       correct by Property 1)
353
      // if (0 < f* < 10^(-x)) then the result is exact
354
      // n = C* * 10^(e+x)  
355
 
356
      if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
357
        res = P128.w[1];
358
        fstar.w[1] = 0;
359
        fstar.w[0] = P128.w[0];
360
      } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
361
        shift = shiftright128[ind - 1]; // 3 <= shift <= 63
362
        res = (P128.w[1] >> shift);
363
        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
364
        fstar.w[0] = P128.w[0];
365
      }
366
      // if (f* > 10^(-x)) then the result is inexact
367
      if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
368
        if (x_sign) {
369
          // if negative and not exact, increment magnitude
370
          res++;
371
        }
372
        *pfpsf |= INEXACT_EXCEPTION;
373
      }
374
      // set exponent to zero as it was negative before.
375
      res = x_sign | 0x31c0000000000000ull | res;
376
      BID_RETURN (res);
377
    } else {    // if exp < 0 and q + exp <= 0
378
      // the result is +0 or -1
379
      if (x_sign) {
380
        res = 0xb1c0000000000001ull;
381
      } else {
382
        res = 0x31c0000000000000ull;
383
      }
384
      *pfpsf |= INEXACT_EXCEPTION;
385
      BID_RETURN (res);
386
    }
387
    break;
388
  case ROUNDING_UP:
389
    if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
390
      // need to shift right -exp digits from the coefficient; exp will be 0
391
      ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
392
      // chop off ind digits from the lower part of C1 
393
      // C1 fits in 64 bits
394
      // calculate C* and f*
395
      // C* is actually floor(C*) in this case
396
      // C* and f* need shifting and masking, as shown by
397
      // shiftright128[] and maskhigh128[]
398
      // 1 <= x <= 16
399
      // kx = 10^(-x) = ten2mk64[ind - 1]
400
      // C* = C1 * 10^(-x)
401
      // the approximation of 10^(-x) was rounded up to 64 bits
402
      __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
403
 
404
      // C* = floor(C*) (logical right shift; C has p decimal digits,
405
      //       correct by Property 1)
406
      // if (0 < f* < 10^(-x)) then the result is exact
407
      // n = C* * 10^(e+x)  
408
 
409
      if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
410
        res = P128.w[1];
411
        fstar.w[1] = 0;
412
        fstar.w[0] = P128.w[0];
413
      } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
414
        shift = shiftright128[ind - 1]; // 3 <= shift <= 63
415
        res = (P128.w[1] >> shift);
416
        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
417
        fstar.w[0] = P128.w[0];
418
      }
419
      // if (f* > 10^(-x)) then the result is inexact
420
      if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
421
        if (!x_sign) {
422
          // if positive and not exact, increment magnitude
423
          res++;
424
        }
425
        *pfpsf |= INEXACT_EXCEPTION;
426
      }
427
      // set exponent to zero as it was negative before.
428
      res = x_sign | 0x31c0000000000000ull | res;
429
      BID_RETURN (res);
430
    } else {    // if exp < 0 and q + exp <= 0
431
      // the result is -0 or +1
432
      if (x_sign) {
433
        res = 0xb1c0000000000000ull;
434
      } else {
435
        res = 0x31c0000000000001ull;
436
      }
437
      *pfpsf |= INEXACT_EXCEPTION;
438
      BID_RETURN (res);
439
    }
440
    break;
441
  case ROUNDING_TO_ZERO:
442
    if ((q + exp) >= 0) {        // exp < 0 and 1 <= -exp <= q
443
      // need to shift right -exp digits from the coefficient; exp will be 0
444
      ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
445
      // chop off ind digits from the lower part of C1 
446
      // C1 fits in 127 bits
447
      // calculate C* and f*
448
      // C* is actually floor(C*) in this case
449
      // C* and f* need shifting and masking, as shown by
450
      // shiftright128[] and maskhigh128[]
451
      // 1 <= x <= 16
452
      // kx = 10^(-x) = ten2mk64[ind - 1]
453
      // C* = C1 * 10^(-x)
454
      // the approximation of 10^(-x) was rounded up to 64 bits
455
      __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
456
 
457
      // C* = floor(C*) (logical right shift; C has p decimal digits,
458
      //       correct by Property 1)
459
      // if (0 < f* < 10^(-x)) then the result is exact
460
      // n = C* * 10^(e+x)  
461
 
462
      if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
463
        res = P128.w[1];
464
        fstar.w[1] = 0;
465
        fstar.w[0] = P128.w[0];
466
      } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
467
        shift = shiftright128[ind - 1]; // 3 <= shift <= 63
468
        res = (P128.w[1] >> shift);
469
        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
470
        fstar.w[0] = P128.w[0];
471
      }
472
      // if (f* > 10^(-x)) then the result is inexact
473
      if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
474
        *pfpsf |= INEXACT_EXCEPTION;
475
      }
476
      // set exponent to zero as it was negative before.
477
      res = x_sign | 0x31c0000000000000ull | res;
478
      BID_RETURN (res);
479
    } else {    // if exp < 0 and q + exp < 0
480
      // the result is +0 or -0
481
      res = x_sign | 0x31c0000000000000ull;
482
      *pfpsf |= INEXACT_EXCEPTION;
483
      BID_RETURN (res);
484
    }
485
    break;
486
  }     // end switch ()
487
  BID_RETURN (res);
488
}
489
 
490
/*****************************************************************************
491
 *  BID64_round_integral_nearest_even
492
 ****************************************************************************/
493
 
494
#if DECIMAL_CALL_BY_REFERENCE
495
void
496
bid64_round_integral_nearest_even (UINT64 * pres,
497
                                   UINT64 *
498
                                   px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
499
                                   _EXC_INFO_PARAM) {
500
  UINT64 x = *px;
501
#else
502
UINT64
503
bid64_round_integral_nearest_even (UINT64 x _EXC_FLAGS_PARAM
504
                                   _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
505
#endif
506
 
507
  UINT64 res = 0xbaddbaddbaddbaddull;
508
  UINT64 x_sign;
509
  int exp;                      // unbiased exponent
510
  // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
511
  BID_UI64DOUBLE tmp1;
512
  int x_nr_bits;
513
  int q, ind, shift;
514
  UINT64 C1;
515
  UINT128 fstar;
516
  UINT128 P128;
517
 
518
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
519
 
520
  // check for NaNs and infinities
521
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
522
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
523
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
524
    else
525
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
526
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
527
      // set invalid flag 
528
      *pfpsf |= INVALID_EXCEPTION;
529
      // return quiet (SNaN) 
530
      res = x & 0xfdffffffffffffffull;
531
    } else {    // QNaN
532
      res = x;
533
    }
534
    BID_RETURN (res);
535
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
536
    res = x_sign | 0x7800000000000000ull;
537
    BID_RETURN (res);
538
  }
539
  // unpack x
540
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
541
    // if the steering bits are 11 (condition will be 0), then
542
    // the exponent is G[0:w+1]
543
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
544
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
545
    if (C1 > 9999999999999999ull) {     // non-canonical
546
      C1 = 0;
547
    }
548
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
549
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
550
    C1 = (x & MASK_BINARY_SIG1);
551
  }
552
 
553
  // if x is 0 or non-canonical
554
  if (C1 == 0) {
555
    if (exp < 0)
556
      exp = 0;
557
    res = x_sign | (((UINT64) exp + 398) << 53);
558
    BID_RETURN (res);
559
  }
560
  // x is a finite non-zero number (not 0, non-canonical, or special)
561
 
562
  // return 0 if (exp <= -(p+1))
563
  if (exp <= -17) {
564
    res = x_sign | 0x31c0000000000000ull;
565
    BID_RETURN (res);
566
  }
567
  // q = nr. of decimal digits in x (1 <= q <= 54)
568
  //  determine first the nr. of bits in x
569
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
570
    q = 16;
571
  } else {      // if x < 2^53
572
    tmp1.d = (double) C1;       // exact conversion
573
    x_nr_bits =
574
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
575
    q = nr_digits[x_nr_bits - 1].digits;
576
    if (q == 0) {
577
      q = nr_digits[x_nr_bits - 1].digits1;
578
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
579
        q++;
580
    }
581
  }
582
 
583
  if (exp >= 0) {        // -exp <= 0
584
    // the argument is an integer already
585
    res = x;
586
    BID_RETURN (res);
587
  } else if ((q + exp) >= 0) {   // exp < 0 and 1 <= -exp <= q
588
    // need to shift right -exp digits from the coefficient; the exp will be 0
589
    ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
590
    // chop off ind digits from the lower part of C1 
591
    // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
592
    // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
593
    C1 = C1 + midpoint64[ind - 1];
594
    // calculate C* and f*
595
    // C* is actually floor(C*) in this case
596
    // C* and f* need shifting and masking, as shown by
597
    // shiftright128[] and maskhigh128[]
598
    // 1 <= x <= 16
599
    // kx = 10^(-x) = ten2mk64[ind - 1]
600
    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
601
    // the approximation of 10^(-x) was rounded up to 64 bits
602
    __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
603
 
604
    // if (0 < f* < 10^(-x)) then the result is a midpoint
605
    //   if floor(C*) is even then C* = floor(C*) - logical right
606
    //       shift; C* has p decimal digits, correct by Prop. 1)
607
    //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
608
    //       shift; C* has p decimal digits, correct by Pr. 1)
609
    // else  
610
    //   C* = floor(C*) (logical right shift; C has p decimal digits,
611
    //       correct by Property 1)
612
    // n = C* * 10^(e+x)  
613
 
614
    if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
615
      res = P128.w[1];
616
      fstar.w[1] = 0;
617
      fstar.w[0] = P128.w[0];
618
    } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
619
      shift = shiftright128[ind - 1];   // 3 <= shift <= 63
620
      res = (P128.w[1] >> shift);
621
      fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
622
      fstar.w[0] = P128.w[0];
623
    }
624
    // if (0 < f* < 10^(-x)) then the result is a midpoint
625
    // since round_to_even, subtract 1 if current result is odd
626
    if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
627
        && (fstar.w[0] < ten2mk64[ind - 1])) {
628
      res--;
629
    }
630
    // set exponent to zero as it was negative before.
631
    res = x_sign | 0x31c0000000000000ull | res;
632
    BID_RETURN (res);
633
  } else {      // if exp < 0 and q + exp < 0
634
    // the result is +0 or -0
635
    res = x_sign | 0x31c0000000000000ull;
636
    BID_RETURN (res);
637
  }
638
}
639
 
640
/*****************************************************************************
641
 *  BID64_round_integral_negative
642
 *****************************************************************************/
643
 
644
#if DECIMAL_CALL_BY_REFERENCE
645
void
646
bid64_round_integral_negative (UINT64 * pres,
647
                               UINT64 *
648
                               px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
649
                               _EXC_INFO_PARAM) {
650
  UINT64 x = *px;
651
#else
652
UINT64
653
bid64_round_integral_negative (UINT64 x _EXC_FLAGS_PARAM
654
                               _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
655
#endif
656
 
657
  UINT64 res = 0xbaddbaddbaddbaddull;
658
  UINT64 x_sign;
659
  int exp;                      // unbiased exponent
660
  // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
661
  BID_UI64DOUBLE tmp1;
662
  int x_nr_bits;
663
  int q, ind, shift;
664
  UINT64 C1;
665
  // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
666
  UINT128 fstar;
667
  UINT128 P128;
668
 
669
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
670
 
671
  // check for NaNs and infinities
672
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
673
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
674
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
675
    else
676
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
677
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
678
      // set invalid flag 
679
      *pfpsf |= INVALID_EXCEPTION;
680
      // return quiet (SNaN) 
681
      res = x & 0xfdffffffffffffffull;
682
    } else {    // QNaN
683
      res = x;
684
    }
685
    BID_RETURN (res);
686
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
687
    res = x_sign | 0x7800000000000000ull;
688
    BID_RETURN (res);
689
  }
690
  // unpack x
691
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
692
    // if the steering bits are 11 (condition will be 0), then
693
    // the exponent is G[0:w+1]
694
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
695
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
696
    if (C1 > 9999999999999999ull) {     // non-canonical
697
      C1 = 0;
698
    }
699
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
700
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
701
    C1 = (x & MASK_BINARY_SIG1);
702
  }
703
 
704
  // if x is 0 or non-canonical
705
  if (C1 == 0) {
706
    if (exp < 0)
707
      exp = 0;
708
    res = x_sign | (((UINT64) exp + 398) << 53);
709
    BID_RETURN (res);
710
  }
711
  // x is a finite non-zero number (not 0, non-canonical, or special)
712
 
713
  // return 0 if (exp <= -p)
714
  if (exp <= -16) {
715
    if (x_sign) {
716
      res = 0xb1c0000000000001ull;
717
    } else {
718
      res = 0x31c0000000000000ull;
719
    }
720
    BID_RETURN (res);
721
  }
722
  // q = nr. of decimal digits in x (1 <= q <= 54)
723
  //  determine first the nr. of bits in x
724
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
725
    q = 16;
726
  } else {      // if x < 2^53
727
    tmp1.d = (double) C1;       // exact conversion
728
    x_nr_bits =
729
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
730
    q = nr_digits[x_nr_bits - 1].digits;
731
    if (q == 0) {
732
      q = nr_digits[x_nr_bits - 1].digits1;
733
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
734
        q++;
735
    }
736
  }
737
 
738
  if (exp >= 0) {        // -exp <= 0
739
    // the argument is an integer already
740
    res = x;
741
    BID_RETURN (res);
742
  } else if ((q + exp) > 0) {    // exp < 0 and 1 <= -exp < q
743
    // need to shift right -exp digits from the coefficient; the exp will be 0
744
    ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
745
    // chop off ind digits from the lower part of C1 
746
    // C1 fits in 64 bits
747
    // calculate C* and f*
748
    // C* is actually floor(C*) in this case
749
    // C* and f* need shifting and masking, as shown by
750
    // shiftright128[] and maskhigh128[]
751
    // 1 <= x <= 16
752
    // kx = 10^(-x) = ten2mk64[ind - 1]
753
    // C* = C1 * 10^(-x)
754
    // the approximation of 10^(-x) was rounded up to 64 bits
755
    __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
756
 
757
    // C* = floor(C*) (logical right shift; C has p decimal digits,
758
    //       correct by Property 1)
759
    // if (0 < f* < 10^(-x)) then the result is exact
760
    // n = C* * 10^(e+x)  
761
 
762
    if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
763
      res = P128.w[1];
764
      fstar.w[1] = 0;
765
      fstar.w[0] = P128.w[0];
766
    } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
767
      shift = shiftright128[ind - 1];   // 3 <= shift <= 63
768
      res = (P128.w[1] >> shift);
769
      fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
770
      fstar.w[0] = P128.w[0];
771
    }
772
    // if (f* > 10^(-x)) then the result is inexact
773
    if (x_sign
774
        && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
775
      // if negative and not exact, increment magnitude
776
      res++;
777
    }
778
    // set exponent to zero as it was negative before.
779
    res = x_sign | 0x31c0000000000000ull | res;
780
    BID_RETURN (res);
781
  } else {      // if exp < 0 and q + exp <= 0
782
    // the result is +0 or -1
783
    if (x_sign) {
784
      res = 0xb1c0000000000001ull;
785
    } else {
786
      res = 0x31c0000000000000ull;
787
    }
788
    BID_RETURN (res);
789
  }
790
}
791
 
792
/*****************************************************************************
793
 *  BID64_round_integral_positive
794
 ****************************************************************************/
795
 
796
#if DECIMAL_CALL_BY_REFERENCE
797
void
798
bid64_round_integral_positive (UINT64 * pres,
799
                               UINT64 *
800
                               px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
801
                               _EXC_INFO_PARAM) {
802
  UINT64 x = *px;
803
#else
804
UINT64
805
bid64_round_integral_positive (UINT64 x _EXC_FLAGS_PARAM
806
                               _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
807
#endif
808
 
809
  UINT64 res = 0xbaddbaddbaddbaddull;
810
  UINT64 x_sign;
811
  int exp;                      // unbiased exponent
812
  // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
813
  BID_UI64DOUBLE tmp1;
814
  int x_nr_bits;
815
  int q, ind, shift;
816
  UINT64 C1;
817
  // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
818
  UINT128 fstar;
819
  UINT128 P128;
820
 
821
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
822
 
823
  // check for NaNs and infinities
824
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
825
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
826
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
827
    else
828
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
829
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
830
      // set invalid flag 
831
      *pfpsf |= INVALID_EXCEPTION;
832
      // return quiet (SNaN) 
833
      res = x & 0xfdffffffffffffffull;
834
    } else {    // QNaN
835
      res = x;
836
    }
837
    BID_RETURN (res);
838
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
839
    res = x_sign | 0x7800000000000000ull;
840
    BID_RETURN (res);
841
  }
842
  // unpack x
843
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
844
    // if the steering bits are 11 (condition will be 0), then
845
    // the exponent is G[0:w+1]
846
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
847
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
848
    if (C1 > 9999999999999999ull) {     // non-canonical
849
      C1 = 0;
850
    }
851
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
852
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
853
    C1 = (x & MASK_BINARY_SIG1);
854
  }
855
 
856
  // if x is 0 or non-canonical
857
  if (C1 == 0) {
858
    if (exp < 0)
859
      exp = 0;
860
    res = x_sign | (((UINT64) exp + 398) << 53);
861
    BID_RETURN (res);
862
  }
863
  // x is a finite non-zero number (not 0, non-canonical, or special)
864
 
865
  // return 0 if (exp <= -p)
866
  if (exp <= -16) {
867
    if (x_sign) {
868
      res = 0xb1c0000000000000ull;
869
    } else {
870
      res = 0x31c0000000000001ull;
871
    }
872
    BID_RETURN (res);
873
  }
874
  // q = nr. of decimal digits in x (1 <= q <= 54)
875
  //  determine first the nr. of bits in x
876
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
877
    q = 16;
878
  } else {      // if x < 2^53
879
    tmp1.d = (double) C1;       // exact conversion
880
    x_nr_bits =
881
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
882
    q = nr_digits[x_nr_bits - 1].digits;
883
    if (q == 0) {
884
      q = nr_digits[x_nr_bits - 1].digits1;
885
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
886
        q++;
887
    }
888
  }
889
 
890
  if (exp >= 0) {        // -exp <= 0
891
    // the argument is an integer already
892
    res = x;
893
    BID_RETURN (res);
894
  } else if ((q + exp) > 0) {    // exp < 0 and 1 <= -exp < q
895
    // need to shift right -exp digits from the coefficient; the exp will be 0
896
    ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
897
    // chop off ind digits from the lower part of C1 
898
    // C1 fits in 64 bits
899
    // calculate C* and f*
900
    // C* is actually floor(C*) in this case
901
    // C* and f* need shifting and masking, as shown by
902
    // shiftright128[] and maskhigh128[]
903
    // 1 <= x <= 16
904
    // kx = 10^(-x) = ten2mk64[ind - 1]
905
    // C* = C1 * 10^(-x)
906
    // the approximation of 10^(-x) was rounded up to 64 bits
907
    __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
908
 
909
    // C* = floor(C*) (logical right shift; C has p decimal digits,
910
    //       correct by Property 1)
911
    // if (0 < f* < 10^(-x)) then the result is exact
912
    // n = C* * 10^(e+x)  
913
 
914
    if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
915
      res = P128.w[1];
916
      fstar.w[1] = 0;
917
      fstar.w[0] = P128.w[0];
918
    } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
919
      shift = shiftright128[ind - 1];   // 3 <= shift <= 63
920
      res = (P128.w[1] >> shift);
921
      fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
922
      fstar.w[0] = P128.w[0];
923
    }
924
    // if (f* > 10^(-x)) then the result is inexact
925
    if (!x_sign
926
        && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
927
      // if positive and not exact, increment magnitude
928
      res++;
929
    }
930
    // set exponent to zero as it was negative before.
931
    res = x_sign | 0x31c0000000000000ull | res;
932
    BID_RETURN (res);
933
  } else {      // if exp < 0 and q + exp <= 0
934
    // the result is -0 or +1
935
    if (x_sign) {
936
      res = 0xb1c0000000000000ull;
937
    } else {
938
      res = 0x31c0000000000001ull;
939
    }
940
    BID_RETURN (res);
941
  }
942
}
943
 
944
/*****************************************************************************
945
 *  BID64_round_integral_zero
946
 ****************************************************************************/
947
 
948
#if DECIMAL_CALL_BY_REFERENCE
949
void
950
bid64_round_integral_zero (UINT64 * pres,
951
                           UINT64 *
952
                           px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
953
                           _EXC_INFO_PARAM) {
954
  UINT64 x = *px;
955
#else
956
UINT64
957
bid64_round_integral_zero (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
958
                           _EXC_INFO_PARAM) {
959
#endif
960
 
961
  UINT64 res = 0xbaddbaddbaddbaddull;
962
  UINT64 x_sign;
963
  int exp;                      // unbiased exponent
964
  // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
965
  BID_UI64DOUBLE tmp1;
966
  int x_nr_bits;
967
  int q, ind, shift;
968
  UINT64 C1;
969
  // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
970
  UINT128 P128;
971
 
972
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
973
 
974
  // check for NaNs and infinities
975
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
976
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
977
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
978
    else
979
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
980
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
981
      // set invalid flag 
982
      *pfpsf |= INVALID_EXCEPTION;
983
      // return quiet (SNaN) 
984
      res = x & 0xfdffffffffffffffull;
985
    } else {    // QNaN
986
      res = x;
987
    }
988
    BID_RETURN (res);
989
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
990
    res = x_sign | 0x7800000000000000ull;
991
    BID_RETURN (res);
992
  }
993
  // unpack x
994
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
995
    // if the steering bits are 11 (condition will be 0), then
996
    // the exponent is G[0:w+1]
997
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
998
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
999
    if (C1 > 9999999999999999ull) {     // non-canonical
1000
      C1 = 0;
1001
    }
1002
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1003
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1004
    C1 = (x & MASK_BINARY_SIG1);
1005
  }
1006
 
1007
  // if x is 0 or non-canonical
1008
  if (C1 == 0) {
1009
    if (exp < 0)
1010
      exp = 0;
1011
    res = x_sign | (((UINT64) exp + 398) << 53);
1012
    BID_RETURN (res);
1013
  }
1014
  // x is a finite non-zero number (not 0, non-canonical, or special)
1015
 
1016
  // return 0 if (exp <= -p)
1017
  if (exp <= -16) {
1018
    res = x_sign | 0x31c0000000000000ull;
1019
    BID_RETURN (res);
1020
  }
1021
  // q = nr. of decimal digits in x (1 <= q <= 54)
1022
  //  determine first the nr. of bits in x
1023
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
1024
    q = 16;
1025
  } else {      // if x < 2^53
1026
    tmp1.d = (double) C1;       // exact conversion
1027
    x_nr_bits =
1028
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1029
    q = nr_digits[x_nr_bits - 1].digits;
1030
    if (q == 0) {
1031
      q = nr_digits[x_nr_bits - 1].digits1;
1032
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1033
        q++;
1034
    }
1035
  }
1036
 
1037
  if (exp >= 0) {        // -exp <= 0
1038
    // the argument is an integer already
1039
    res = x;
1040
    BID_RETURN (res);
1041
  } else if ((q + exp) >= 0) {   // exp < 0 and 1 <= -exp <= q
1042
    // need to shift right -exp digits from the coefficient; the exp will be 0
1043
    ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1044
    // chop off ind digits from the lower part of C1 
1045
    // C1 fits in 127 bits
1046
    // calculate C* and f*
1047
    // C* is actually floor(C*) in this case
1048
    // C* and f* need shifting and masking, as shown by
1049
    // shiftright128[] and maskhigh128[]
1050
    // 1 <= x <= 16
1051
    // kx = 10^(-x) = ten2mk64[ind - 1]
1052
    // C* = C1 * 10^(-x)
1053
    // the approximation of 10^(-x) was rounded up to 64 bits
1054
    __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1055
 
1056
    // C* = floor(C*) (logical right shift; C has p decimal digits,
1057
    //       correct by Property 1)
1058
    // if (0 < f* < 10^(-x)) then the result is exact
1059
    // n = C* * 10^(e+x)  
1060
 
1061
    if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1062
      res = P128.w[1];
1063
      // redundant fstar.w[1] = 0;
1064
      // redundant fstar.w[0] = P128.w[0];
1065
    } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1066
      shift = shiftright128[ind - 1];   // 3 <= shift <= 63
1067
      res = (P128.w[1] >> shift);
1068
      // redundant fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
1069
      // redundant fstar.w[0] = P128.w[0];
1070
    }
1071
    // if (f* > 10^(-x)) then the result is inexact
1072
    // if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind-1])){
1073
    //   // redundant
1074
    // }
1075
    // set exponent to zero as it was negative before.
1076
    res = x_sign | 0x31c0000000000000ull | res;
1077
    BID_RETURN (res);
1078
  } else {      // if exp < 0 and q + exp < 0
1079
    // the result is +0 or -0
1080
    res = x_sign | 0x31c0000000000000ull;
1081
    BID_RETURN (res);
1082
  }
1083
}
1084
 
1085
/*****************************************************************************
1086
 *  BID64_round_integral_nearest_away
1087
 ****************************************************************************/
1088
 
1089
#if DECIMAL_CALL_BY_REFERENCE
1090
void
1091
bid64_round_integral_nearest_away (UINT64 * pres,
1092
                                   UINT64 *
1093
                                   px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1094
                                   _EXC_INFO_PARAM) {
1095
  UINT64 x = *px;
1096
#else
1097
UINT64
1098
bid64_round_integral_nearest_away (UINT64 x _EXC_FLAGS_PARAM
1099
                                   _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1100
#endif
1101
 
1102
  UINT64 res = 0xbaddbaddbaddbaddull;
1103
  UINT64 x_sign;
1104
  int exp;                      // unbiased exponent
1105
  // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1106
  BID_UI64DOUBLE tmp1;
1107
  int x_nr_bits;
1108
  int q, ind, shift;
1109
  UINT64 C1;
1110
  UINT128 P128;
1111
 
1112
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
1113
 
1114
  // check for NaNs and infinities
1115
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
1116
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
1117
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
1118
    else
1119
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
1120
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
1121
      // set invalid flag 
1122
      *pfpsf |= INVALID_EXCEPTION;
1123
      // return quiet (SNaN) 
1124
      res = x & 0xfdffffffffffffffull;
1125
    } else {    // QNaN
1126
      res = x;
1127
    }
1128
    BID_RETURN (res);
1129
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
1130
    res = x_sign | 0x7800000000000000ull;
1131
    BID_RETURN (res);
1132
  }
1133
  // unpack x
1134
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1135
    // if the steering bits are 11 (condition will be 0), then
1136
    // the exponent is G[0:w+1]
1137
    exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
1138
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1139
    if (C1 > 9999999999999999ull) {     // non-canonical
1140
      C1 = 0;
1141
    }
1142
  } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1143
    exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1144
    C1 = (x & MASK_BINARY_SIG1);
1145
  }
1146
 
1147
  // if x is 0 or non-canonical
1148
  if (C1 == 0) {
1149
    if (exp < 0)
1150
      exp = 0;
1151
    res = x_sign | (((UINT64) exp + 398) << 53);
1152
    BID_RETURN (res);
1153
  }
1154
  // x is a finite non-zero number (not 0, non-canonical, or special)
1155
 
1156
  // return 0 if (exp <= -(p+1))
1157
  if (exp <= -17) {
1158
    res = x_sign | 0x31c0000000000000ull;
1159
    BID_RETURN (res);
1160
  }
1161
  // q = nr. of decimal digits in x (1 <= q <= 54)
1162
  //  determine first the nr. of bits in x
1163
  if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
1164
    q = 16;
1165
  } else {      // if x < 2^53
1166
    tmp1.d = (double) C1;       // exact conversion
1167
    x_nr_bits =
1168
      1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1169
    q = nr_digits[x_nr_bits - 1].digits;
1170
    if (q == 0) {
1171
      q = nr_digits[x_nr_bits - 1].digits1;
1172
      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1173
        q++;
1174
    }
1175
  }
1176
 
1177
  if (exp >= 0) {        // -exp <= 0
1178
    // the argument is an integer already
1179
    res = x;
1180
    BID_RETURN (res);
1181
  } else if ((q + exp) >= 0) {   // exp < 0 and 1 <= -exp <= q
1182
    // need to shift right -exp digits from the coefficient; the exp will be 0
1183
    ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1184
    // chop off ind digits from the lower part of C1 
1185
    // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
1186
    // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
1187
    C1 = C1 + midpoint64[ind - 1];
1188
    // calculate C* and f*
1189
    // C* is actually floor(C*) in this case
1190
    // C* and f* need shifting and masking, as shown by
1191
    // shiftright128[] and maskhigh128[]
1192
    // 1 <= x <= 16
1193
    // kx = 10^(-x) = ten2mk64[ind - 1]
1194
    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
1195
    // the approximation of 10^(-x) was rounded up to 64 bits
1196
    __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1197
 
1198
    // if (0 < f* < 10^(-x)) then the result is a midpoint
1199
    //   C* = floor(C*) - logical right shift; C* has p decimal digits, 
1200
    //       correct by Prop. 1)
1201
    // else
1202
    //   C* = floor(C*) (logical right shift; C has p decimal digits,
1203
    //       correct by Property 1)
1204
    // n = C* * 10^(e+x)
1205
 
1206
    if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1207
      res = P128.w[1];
1208
    } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1209
      shift = shiftright128[ind - 1];   // 3 <= shift <= 63
1210
      res = (P128.w[1] >> shift);
1211
    }
1212
    // midpoints are already rounded correctly
1213
    // set exponent to zero as it was negative before.
1214
    res = x_sign | 0x31c0000000000000ull | res;
1215
    BID_RETURN (res);
1216
  } else {      // if exp < 0 and q + exp < 0
1217
    // the result is +0 or -0
1218
    res = x_sign | 0x31c0000000000000ull;
1219
    BID_RETURN (res);
1220
  }
1221
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.