GnuCOBOL  2.0
A free COBOL compiler
numeric.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2001-2012, 2014-2015 Free Software Foundation, Inc.
3  Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman
4 
5  This file is part of GnuCOBOL.
6 
7  The GnuCOBOL runtime library is free software: you can redistribute it
8  and/or modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation, either version 3 of the
10  License, or (at your option) any later version.
11 
12  GnuCOBOL is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GnuCOBOL. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 #include "config.h"
23 
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE 1
26 #endif
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <errno.h>
35 
36 #include <math.h>
37 #ifdef HAVE_FINITE_IEEEFP_H
38 #include <ieeefp.h>
39 #endif
40 
41 /* Force symbol exports */
42 #define COB_LIB_EXPIMP
43 
44 #include "libcob.h"
45 #include "coblocal.h"
46 
47 #define DECIMAL_CHECK(d1,d2) \
48  if (unlikely(d1->scale == COB_DECIMAL_NAN || \
49  d2->scale == COB_DECIMAL_NAN)) { \
50  d1->scale = COB_DECIMAL_NAN; \
51  return; \
52  }
53 
54 /* Local variables */
55 
57 
58 static const unsigned char packed_bytes[] = {
59  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
60  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
61  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
62  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
63  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
64  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
65  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
66  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
67  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
68  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
69 };
70 
71 #if 0 /* RXWRXW - IEEE 754 */
72 static const unsigned char bits8[] = {
73  8, 7, 6, 6, 5, 5, 5, 5,
74  4, 4, 4, 4, 4, 4, 4, 4,
75  3, 3, 3, 3, 3, 3, 3, 3,
76  3, 3, 3, 3, 3, 3, 3, 3,
77  2, 2, 2, 2, 2, 2, 2, 2,
78  2, 2, 2, 2, 2, 2, 2, 2,
79  2, 2, 2, 2, 2, 2, 2, 2,
80  2, 2, 2, 2, 2, 2, 2, 2,
81  1, 1, 1, 1, 1, 1, 1, 1,
82  1, 1, 1, 1, 1, 1, 1, 1,
83  1, 1, 1, 1, 1, 1, 1, 1,
84  1, 1, 1, 1, 1, 1, 1, 1,
85  1, 1, 1, 1, 1, 1, 1, 1,
86  1, 1, 1, 1, 1, 1, 1, 1,
87  1, 1, 1, 1, 1, 1, 1, 1,
88  1, 1, 1, 1, 1, 1, 1, 1,
89  0, 0, 0, 0, 0, 0, 0, 0,
90  0, 0, 0, 0, 0, 0, 0, 0,
91  0, 0, 0, 0, 0, 0, 0, 0,
92  0, 0, 0, 0, 0, 0, 0, 0,
93  0, 0, 0, 0, 0, 0, 0, 0,
94  0, 0, 0, 0, 0, 0, 0, 0,
95  0, 0, 0, 0, 0, 0, 0, 0,
96  0, 0, 0, 0, 0, 0, 0, 0,
97  0, 0, 0, 0, 0, 0, 0, 0,
98  0, 0, 0, 0, 0, 0, 0, 0,
99  0, 0, 0, 0, 0, 0, 0, 0,
100  0, 0, 0, 0, 0, 0, 0, 0,
101  0, 0, 0, 0, 0, 0, 0, 0,
102  0, 0, 0, 0, 0, 0, 0, 0,
103  0, 0, 0, 0, 0, 0, 0, 0,
104  0, 0, 0, 0, 0, 0, 0, 0
105 };
106 #endif
107 
112 
114 
115 static mpz_t cob_mexp;
116 static mpz_t cob_mpzt;
117 static mpz_t cob_mpzt2;
118 static mpz_t cob_mpz_ten34m1;
119 static mpz_t cob_mpz_ten16m1;
121 
122 static mpf_t cob_mpft;
123 static mpf_t cob_mpft_get;
124 
125 static unsigned char packed_value[20];
127 
128 
129 #ifdef COB_EXPERIMENTAL
130 
131 #if GMP_NAIL_BITS != 0
132 #error NAILS not supported
133 #endif
134 
135 #define COB_MAX_LL COB_S64_C(9223372036854775807)
136 
137 static void
138 mpz_set_ull (mpz_ptr dest, const cob_u64_t val)
139 {
140  size_t size;
141 
142  size = (val != 0);
143  dest->_mp_d[0] = val & GMP_NUMB_MASK;
144 #if GMP_LIMB_BITS < 64
145  if (val > GMP_NUMB_MAX) {
146  dest->_mp_d[1] = val >> GMP_NUMB_BITS;
147  size = 2;
148  }
149 #endif
150  dest->_mp_size = size;
151 }
152 
153 static void
154 mpz_set_sll (mpz_ptr dest, const cob_s64_t val)
155 {
156  cob_u64_t vtmp;
157  size_t size;
158 
159  vtmp = (cob_u64_t)(val >= 0 ? (cob_u64_t)val : -(cob_u64_t)val);
160  size = (vtmp != 0);
161  dest->_mp_d[0] = vtmp & GMP_NUMB_MASK;
162 #if GMP_LIMB_BITS < 64
163  if (vtmp > GMP_NUMB_MAX) {
164  dest->_mp_d[1] = vtmp >> GMP_NUMB_BITS;
165  size = 2;
166  }
167 #endif
168  dest->_mp_size = (val >= 0) ? size : -size;
169 }
170 
171 static cob_u64_t
172 mpz_get_ull (const mpz_ptr src)
173 {
174  size_t size;
175 
176  size = mpz_size (src);
177  if (!size) {
178  return 0;
179  }
180 #if GMP_LIMB_BITS > 32
181  return (cob_u64_t)src->_mp_d[0];
182 #else
183  if (size < 2) {
184  return (cob_u64_t)src->_mp_d[0];
185  }
186  return (cob_u64_t)src->_mp_d[0] |
187  ((cob_u64_t)src->_mp_d[1] << GMP_NUMB_BITS);
188 #endif
189 }
190 
191 static cob_s64_t
192 mpz_get_sll (const mpz_ptr src)
193 {
194  int size;
195  cob_u64_t vtmp;
196 
197  size = src->_mp_size;
198  if (!size) {
199  return 0;
200  }
201  vtmp = (cob_u64_t)src->_mp_d[0];
202 #if GMP_LIMB_BITS < 64
203  if (mpz_size (src) > 1) {
204  vtmp |= (cob_u64_t)src->_mp_d[1] << GMP_NUMB_BITS;
205  }
206 #endif
207  if (size > 0) {
208  return (cob_s64_t) vtmp & COB_MAX_LL;
209  }
210  return ~(((cob_s64_t) vtmp - 1LL) & COB_MAX_LL);
211 }
212 
213 #endif /* COB_EXPERIMENTAL */
214 
215 
216 void
217 cob_gmp_free (void * ptr) {
218 /* mpir/gmp free functions */
219 #ifdef HAVE_MP_GET_MEMORY_FUNCTIONS
220  void (*freefunc)(void *, size_t);
221  mp_get_memory_functions (NULL, NULL, &freefunc);
222  freefunc (ptr, strlen((char*) ptr) + 1);
223 #else
224  free (ptr);
225 #endif
226 }
227 
228 static COB_INLINE COB_A_INLINE void
229 num_byte_memcpy (unsigned char *s1, const unsigned char *s2, size_t size)
230 {
231  do {
232  *s1++ = *s2++;
233  } while (--size);
234 }
235 
238 {
239  cob_s64_t n = 0;
240  size_t fsiz = 8U - f->size;
241 
242 #ifndef WORDS_BIGENDIAN
243  if (COB_FIELD_BINARY_SWAP (f)) {
244  num_byte_memcpy ((unsigned char *)&n, f->data, f->size);
245  n = COB_BSWAP_64 (n);
246  /* Shift with sign */
247  n >>= 8 * fsiz;
248  } else {
249  num_byte_memcpy (((unsigned char *)&n) + fsiz, f->data, f->size);
250  /* Shift with sign */
251  n >>= 8 * fsiz;
252  }
253 #else /* WORDS_BIGENDIAN */
254  num_byte_memcpy ((unsigned char *)&n, f->data, f->size);
255  /* Shift with sign */
256  n >>= 8 * fsiz;
257 #endif /* WORDS_BIGENDIAN */
258 
259  return n;
260 }
261 
264 {
265  cob_u64_t n = 0;
266  size_t fsiz = 8U - f->size;
267 
268 #ifndef WORDS_BIGENDIAN
269  if (COB_FIELD_BINARY_SWAP (f)) {
270  num_byte_memcpy (((unsigned char *)&n) + fsiz, f->data, f->size);
271  n = COB_BSWAP_64 (n);
272  } else {
273  num_byte_memcpy ((unsigned char *)&n, f->data, f->size);
274  }
275 #else /* WORDS_BIGENDIAN */
276  num_byte_memcpy (((unsigned char *)&n) + fsiz, f->data, f->size);
277 #endif /* WORDS_BIGENDIAN */
278 
279  return n;
280 }
281 
282 static COB_INLINE COB_A_INLINE void
284 {
285 #ifndef WORDS_BIGENDIAN
286  unsigned char *s;
287 
288  if (COB_FIELD_BINARY_SWAP (f)) {
289  n = COB_BSWAP_64 (n);
290  s = ((unsigned char *)&n) + 8 - f->size;
291  } else {
292  s = (unsigned char *)&n;
293  }
294  num_byte_memcpy (f->data, s, f->size);
295 #else /* WORDS_BIGENDIAN */
296  num_byte_memcpy (f->data, ((unsigned char *)&n) + 8 - f->size, f->size);
297 #endif /* WORDS_BIGENDIAN */
298 }
299 
300 static COB_INLINE COB_A_INLINE void
302 {
303 #ifndef WORDS_BIGENDIAN
304  unsigned char *s;
305 
306  if (COB_FIELD_BINARY_SWAP (f)) {
307  n = COB_BSWAP_64 (n);
308  s = ((unsigned char *)&n) + 8 - f->size;
309  } else {
310  s = (unsigned char *)&n;
311  }
312  num_byte_memcpy (f->data, s, f->size);
313 #else /* WORDS_BIGENDIAN */
314  num_byte_memcpy (f->data, ((unsigned char *)&n) + 8 - f->size, f->size);
315 #endif /* WORDS_BIGENDIAN */
316 }
317 
318 /* Decimal number */
319 
320 void
322 {
323  mpz_init2 (d->value, COB_MPZ_DEF);
324  d->scale = 0;
325 }
326 
327 void
329 {
330 #ifdef COB_LI_IS_LL
331  mpz_set_si (d->value, (cob_sli_t)n);
332 #else
333  cob_u64_t uval;
334  cob_u32_t negative;
335 
336  negative = 0;
337  if (n < 0) {
338  negative = 1;
339  uval = (cob_u64_t)-n;
340  } else {
341  uval = (cob_u64_t)n;
342  }
343  mpz_set_ui (d->value, (cob_uli_t)(uval >> 32));
344  mpz_mul_2exp (d->value, d->value, 32);
345  mpz_add_ui (d->value, d->value, (cob_uli_t)(uval & 0xFFFFFFFFU));
346  if (negative) {
347  mpz_neg (d->value, d->value);
348  }
349 #endif
350  d->scale = 0;
351 }
352 
353 /* Decimal <-> Decimal */
354 
355 static COB_INLINE COB_A_INLINE void
357 {
358  mpz_set (dst->value, src->value);
359  dst->scale = src->scale;
360 }
361 
362 /* Decimal print */
363 static void
365 {
366  int scale;
367 
368  if (unlikely(d->scale == COB_DECIMAL_NAN)) {
369  fprintf (fp, "(Nan)");
370  return;
371  }
372  if (unlikely(d->scale == COB_DECIMAL_INF)) {
373  fprintf (fp, "(Inf)");
374  return;
375  }
376  if (!mpz_sgn (d->value)) {
377  fprintf (fp, "0E0");
378  return;
379  }
380  mpz_set (cob_mpzt2, d->value);
381  scale = d->scale;
382  for ( ; ; ) {
383  if (!mpz_divisible_ui_p (cob_mpzt2, 10UL)) {
384  break;
385  }
386  mpz_tdiv_q_ui (cob_mpzt2, cob_mpzt2, 10UL);
387  scale--;
388  }
389  gmp_fprintf (fp, "%ZdE%d", cob_mpzt2, -scale);
390 }
391 
392 /* d->value *= 10^n, d->scale += n */
393 static void
394 shift_decimal (cob_decimal *d, const int n)
395 {
396  if (n == 0) {
397  return;
398  }
399  if (n > 0) {
400  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)n);
401  mpz_mul (d->value, d->value, cob_mexp);
402  } else {
403  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-n);
404  mpz_tdiv_q (d->value, d->value, cob_mexp);
405  }
406  d->scale += n;
407 }
408 
409 /* Align decimal */
410 static void
412 {
413  if (d1->scale < d2->scale) {
414  shift_decimal (d1, d2->scale - d1->scale);
415  } else if (d1->scale > d2->scale) {
416  shift_decimal (d2, d1->scale - d2->scale);
417  }
418 }
419 
420 /* IEEE 754 floats */
421 
422 #if 0 /* Clamp */
423 static unsigned int
424 cob_clamp_decimal (cob_decimal *d, const unsigned int expomin,
425  const unsigned int expomax, const unsigned int sigfbits)
426 {
427  int size;
428  unsigned int count;
429 
430  if (!mpz_sgn (d->value)) {
431  /* Value is zero */
432  d->scale = 0;
433  return 0;
434  }
435  /* Remove trailing 0 from decimal places (if any) */
436  for ( ; d->scale > 0; d->scale--) {
437  if (!mpz_divisible_ui_p (d->value, 10UL)) {
438  break;
439  }
440  mpz_tdiv_q_ui (d->value, d->value, 10UL);
441  }
442  if (d->scale) {
443  /* Have decimal places */
444  size = (int)mpz_sizeinbase (d->value, 2);
445  for (; size > sigfbits && d->scale; d->scale--) {
446  mpz_tdiv_q_ui (d->value, d->value, 10UL);
447  size = (int)mpz_sizeinbase (d->value, 2);
448  }
449  return expomin - (unsigned int)d->scale;
450  }
451  for (count = 0; count < expomax; ++count) {
452  if (!mpz_divisible_ui_p (d->value, 10UL)) {
453  break;
454  }
455  mpz_tdiv_q_ui (d->value, d->value, 10UL);
456  }
457  return expomin + count;
458 }
459 #endif
460 
461 #if 0 /* Binary */
462 static void
463 cob_decimal_set_ieee_binary (cob_decimal *d, const cob_field *f)
464 {
465  unsigned char *data;
466  unsigned int n;
467  unsigned int expo;
468  unsigned char bd[16];
469 
470  data = f->data;
471  expo = ((data[0] & 0x7FU) << 8U) | data[1];
472  if (expo == 0x7FFFU) {
473  mpz_set_ui (d->value, 1UL);
474  d->scale = COB_DECIMAL_NAN;
475  return;
476  }
477 }
478 #endif
479 
480 static int
482 {
483  int sign;
484  cob_u64_t expo;
485  cob_u64_t data;
486 
487  sign = mpz_sgn (d->value);
488  if (!sign) {
489  memset (f->data, 0, (size_t)8);
490  return 0;
491  }
492  if (sign < 0) {
493  mpz_neg (d->value, d->value);
494  }
495  for ( ; ; d->scale--) {
496  if (!mpz_divisible_ui_p (d->value, 10UL)) {
497  break;
498  }
499  mpz_tdiv_q_ui (d->value, d->value, 10UL);
500  }
501  if (mpz_cmpabs (d->value, cob_mpz_ten16m1) >= 0) {
502  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
504  return cobglobptr->cob_exception_code;
505  }
506 #if 0 /* RXWRXW - FP Trunc */
507  if (d->scale > 0 ) {
508  for ( ; d->scale; ) {
509 #endif
510  for ( ; ; ) {
511  mpz_tdiv_q_ui (d->value, d->value, 10UL);
512  d->scale--;
513  if (mpz_cmpabs (d->value, cob_mpz_ten16m1) < 0) {
514  break;
515  }
516  }
517 #if 0 /* RXWRXW - FP Trunc */
518  } else {
519  mpz_tdiv_r (d->value, d->value, cob_mpze10[16]);
520  }
521 #endif
522  }
523  if (d->scale < -398 || d->scale > 369) {
525  return cobglobptr->cob_exception_code;
526  }
527  expo = 398 - d->scale;
528 #if 0 /* Clamp */
529  expo = cob_clamp_decimal (d, 398U, 369U, 53U);
530 #endif
531 
532  data = 0;
533  mpz_export (&data, NULL, -1, (size_t)8, COB_MPZ_ENDIAN,
534  (size_t)0, d->value);
535  /* Move in exponent */
536  if (mpz_sizeinbase (d->value, 2) > 51U) {
537  data &= COB_64_SIGF_2;
538  data |= (expo << 51U) | COB_DEC_EXTEND | COB_64_OR_EXTEND;
539  } else {
540  data &= COB_64_SIGF_1;
541  data |= (expo << 53U);
542  }
543  if (sign < 0) {
544  data |= COB_DEC_SIGN;
545  }
546  memcpy (f->data, &data, (size_t)8);
547  return 0;
548 }
549 
550 static void
552 {
553  cob_u64_t expo;
554  cob_u64_t sign;
555  cob_u64_t data;
556 
557  /* bit 0 : sign bit */
558  /* bits 1 - 4 : combination field */
559  /* combination = 15 (all bits set) is inf/nan */
560  /* combination > 11 (bits 1100) is extended exponent */
561  /* Exponent length - 10 bits */
562 
563  memcpy (&data, f->data, sizeof(data));
564  sign = data & COB_DEC_SIGN;
565  if (COB_64_IS_SPECIAL (data)) {
566  /* Inf / Nan */
567  mpz_set_ui (d->value, 1UL);
568  d->scale = COB_DECIMAL_NAN;
569  return;
570  }
571  if (COB_64_IS_EXTEND (data)) {
572  expo = (data & COB_64_EXPO_2) >> 51U;
573  data &= COB_64_SIGF_2;
574  data |= COB_64_OR_EXTEND;
575  if (data > COB_U64_C(9999999999999999)) {
576  mpz_set_ui (d->value, 0UL);
577  d->scale = 0;
578  return;
579  }
580  } else {
581  expo = (data & COB_64_EXPO_1) >> 53U;
582  data &= COB_64_SIGF_1;
583  }
584  if (!data) {
585  /* Significand 0 */
586  mpz_set_ui (d->value, 0UL);
587  d->scale = 0;
588  return;
589  }
590 #ifdef COB_LI_IS_LL
591  mpz_set_ui (d->value, data);
592 #else
593  mpz_set_ui (d->value, (cob_uli_t)(data >> 32));
594  mpz_mul_2exp (d->value, d->value, 32);
595  mpz_add_ui (d->value, d->value, (cob_uli_t)(data & 0xFFFFFFFFU));
596 #endif
597 
598  d->scale = (int)expo - 398;
599  if (d->scale > 0) {
600  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d->scale);
601  mpz_mul (d->value, d->value, cob_mexp);
602  d->scale = 0;
603  } else if (d->scale < 0) {
604  d->scale = -(d->scale);
605  }
606  if (sign) {
607  mpz_neg (d->value, d->value);
608  }
609 }
610 
611 static int
613 {
614  cob_u64_t expo;
615  cob_u64_t data[2];
616  int sign;
617 
618  sign = mpz_sgn (d->value);
619  if (!sign) {
620  memset (f->data, 0, (size_t)16);
621  return 0;
622  }
623  if (sign < 0) {
624  mpz_neg (d->value, d->value);
625  }
626  for ( ; ; d->scale--) {
627  if (!mpz_divisible_ui_p (d->value, 10UL)) {
628  break;
629  }
630  mpz_tdiv_q_ui (d->value, d->value, 10UL);
631  }
632  if (mpz_cmpabs (d->value, cob_mpz_ten34m1) >= 0) {
633  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
635  return cobglobptr->cob_exception_code;
636  }
637 #if 0 /* RXWRXW - FP Trunc */
638  if (d->scale > 0 ) {
639  for ( ; d->scale; ) {
640 #endif
641  for ( ; ; ) {
642  mpz_tdiv_q_ui (d->value, d->value, 10UL);
643  d->scale--;
644  if (mpz_cmpabs (d->value, cob_mpz_ten34m1) < 0) {
645  break;
646  }
647  }
648 #if 0 /* RXWRXW - FP Trunc */
649  } else {
650  mpz_tdiv_r (d->value, d->value, cob_mpze10[34]);
651  }
652 #endif
653  }
654  if (d->scale < -6176 || d->scale > 6111) {
656  return cobglobptr->cob_exception_code;
657  }
658  expo = 6176 - d->scale;
659 #if 0 /* Clamp */
660  expo = cob_clamp_decimal (d, 6176U, 6111U, 113U);
661 #endif
662 
663  data[0] = 0;
664  data[1] = 0;
665  mpz_export (data, NULL, -1, (size_t)16, COB_MPZ_ENDIAN,
666  (size_t)0, d->value);
667  /* Move in exponent */
668 #if 0 /* IEEE canonical */
669  if (mpz_sizeinbase (d->value, 2) > 113U) {
670  COB_128_MSW(data) &= COB_128_SIGF_2;
671  COB_128_MSW(data) |= (expo << 47U) |
673  } else {
674 #endif
675  COB_128_MSW(data) &= COB_128_SIGF_1;
676  COB_128_MSW(data) |= (expo << 49U);
677 #if 0 /* IEEE canonical */
678  }
679 #endif
680  if (sign < 0) {
681  COB_128_MSW(data) |= COB_DEC_SIGN;
682  }
683  memcpy (f->data, data, (size_t)16);
684  return 0;
685 }
686 
687 static void
689 {
690  cob_u64_t expo;
691  cob_u64_t sign;
692  cob_u64_t data[2];
693 
694  /* bit 0 : sign bit */
695  /* bits 1 - 4 : combination field */
696  /* combination = 15 (all bits set) is inf/nan */
697  /* combination > 11 (bits 1100) is extended exponent */
698  /* Exponent length - 14 bits */
699 
700  memcpy (data, f->data, sizeof(data));
701  sign = COB_128_MSW(data) & COB_DEC_SIGN;
702  if (COB_128_IS_SPECIAL (data)) {
703  /* Inf / Nan */
704  mpz_set_ui (d->value, 1UL);
705  d->scale = COB_DECIMAL_NAN;
706  return;
707  }
708  if (COB_128_IS_EXTEND (data)) {
709  expo = (COB_128_MSW(data) & COB_128_EXPO_2) >> 47U;
710  COB_128_MSW(data) &= COB_128_SIGF_2;
712 #if 0 /* RXWRXW - IEEE cap at 34 digits */
713  /* Non-canonical */
714  mpz_set_ui (d->value, 0);
715  d->scale = 0;
716  return;
717 #endif
718  } else {
719  expo = (COB_128_MSW(data) & COB_128_EXPO_1) >> 49U;
720  COB_128_MSW(data) &= COB_128_SIGF_1;
721  }
722  if (!COB_128_MSW(data) && !COB_128_LSW(data)) {
723  /* Significand 0 */
724  mpz_set_ui (d->value, 0UL);
725  d->scale = 0;
726  return;
727  }
728 #ifdef COB_LI_IS_LL
729  mpz_set_ui (d->value, COB_128_MSW(data));
730  mpz_mul_2exp (d->value, d->value, 64UL);
731  mpz_add_ui (d->value, d->value, COB_128_LSW(data));
732 #else
733  /* RXWRXW - Fixme */
734  mpz_set_ui (d->value, (cob_uli_t)(COB_128_MSW(data) >> 32U));
735  mpz_mul_2exp (d->value, d->value, 32UL);
736  mpz_add_ui (d->value, d->value, (cob_uli_t)(COB_128_MSW(data) & 0xFFFFFFFFU));
737  mpz_mul_2exp (d->value, d->value, 32UL);
738  mpz_add_ui (d->value, d->value, (cob_uli_t)(COB_128_LSW(data) >> 32U));
739  mpz_mul_2exp (d->value, d->value, 32UL);
740  mpz_add_ui (d->value, d->value, (cob_uli_t)(COB_128_LSW(data) & 0xFFFFFFFFU));
741 #endif
742 
743  if (mpz_cmpabs (d->value, cob_mpz_ten34m1) >= 0) {
744  /* Non-canonical */
745  mpz_set_ui (d->value, 0UL);
746  d->scale = 0;
747  return;
748  }
749  d->scale = (int)expo - 6176;
750  if (d->scale > 0) {
751  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d->scale);
752  mpz_mul (d->value, d->value, cob_mexp);
753  d->scale = 0;
754  } else if (d->scale < 0) {
755  d->scale = -(d->scale);
756  }
757  if (sign) {
758  mpz_neg (d->value, d->value);
759  }
760 }
761 
762 #if 0 /* RXWRXW - Endian */
763 static void
765 {
766  unsigned int sign;
767  unsigned int expo;
768  unsigned int comb;
769  unsigned char data[16];
770 
771  /* bit 0 : sign bit */
772  /* bits 1 - 4 : combination field */
773  /* combination = 15 (all bits set) is inf/nan */
774  /* combination > 11 (bits 1100) is extended exponent */
775  /* Exponent length - 14 bits */
776  memcpy (data, f->data, 16);
777  sign = data[0] >> 7U;
778  comb = (data[0] & 0x78U) >> 3U;
779  if (comb == 15U) {
780  mpz_set_ui (d->value, 1UL);
781  d->scale = COB_DECIMAL_NAN;
782  return;
783  }
784  if (comb > 11U) {
785  /* 5 bits from byte 0 - 8 bits from byte 1 - 1 bit from byte 2 */
786  expo = ((data[0] & 0x1FU) << 9U) | (data[1] << 1U) |
787  (data[2] >> 7U);
788  /* Mask out expo bit in byte 2 */
789  data[2] &= 0x7FU;
790  /* Set 100 bits left of significand in byte 1*/
791  data[1] = 0x02U;
792  } else {
793  /* 7 bits from byte 0 - 7 bits from byte 1 */
794  expo = ((data[0] & 0x7FU) << 7U) | (data[1] >> 1U);
795  /* Mask out expo bits */
796  data[1] &= 0x01U;
797  }
798  mpz_import (d->value, 15, 1, 1, 1, 0, &data[1]);
799  if (!mpz_sgn (d->value)) {
800  /* Significand 0 */
801  d->scale = 0;
802  return;
803  }
804  if (sign) {
805  mpz_neg (d->value, d->value);
806  }
807  d->scale = (int)expo - 6176;
808  if (d->scale > 0) {
809  mpz_ui_pow_ui (cob_mexp, 10, (cob_uli_t)d->scale);
810  mpz_mul (d->value, d->value, cob_mexp);
811  d->scale = 0;
812  } else if (d->scale < 0) {
813  d->scale = -(d->scale);
814  }
815 }
816 #endif
817 
818 /* Double */
819 
820 static void
822 {
823  char *p;
824  char *q;
825  cob_u64_t t1;
826  cob_sli_t scale;
827  cob_sli_t len;
828  int sign;
829  union {
830  double d1;
831  cob_u64_t l1;
832  } ud;
833 
834  memset (&t1, ' ', sizeof(t1));
835  ud.d1 = v;
836  if (ud.l1 == 0 || ud.l1 == t1 || !finite (v)) {
837  mpz_set_ui (d->value, 0UL);
838  d->scale = 0;
839  return;
840  }
841 
842  sign = 0;
843  mpf_set_d (cob_mpft, v);
844 
845  q = mpf_get_str (NULL, &scale, 10, (size_t)96, cob_mpft);
846  if (!*q) {
847  mpz_set_ui (d->value, 0UL);
848  d->scale = 0;
849  cob_gmp_free(q);
850  return;
851  }
852  p = q;
853  if (*p == '-') {
854  sign = 1;
855  ++p;
856  }
857 
858  mpz_set_str (d->value, p, 10);
859 
860  len = (cob_sli_t)strlen (p);
861  len -= scale;
862  if (len >= 0) {
863  d->scale = len;
864  } else {
865  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-len);
866  mpz_mul (d->value, d->value, cob_mexp);
867  d->scale = 0;
868  }
869 
870  if (sign) {
871  mpz_neg (d->value, d->value);
872  }
873  cob_gmp_free(q);
874 }
875 
876 static double
878 {
879  double v;
880  cob_sli_t n;
881 
882  v = 0.0;
883  if (unlikely(mpz_size (d->value) == 0)) {
884  return v;
885  }
886 
887  mpf_set_z (cob_mpft, d->value);
888 
889  n = d->scale;
890  if (n < 0) {
891  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-n);
892  mpf_set_z (cob_mpft_get, cob_mexp);
893  mpf_mul (cob_mpft, cob_mpft, cob_mpft_get);
894  } else if (n > 0) {
895  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)n);
896  mpf_set_z (cob_mpft_get, cob_mexp);
897  mpf_div (cob_mpft, cob_mpft, cob_mpft_get);
898  }
899 
900  v = mpf_get_d (cob_mpft);
901  if (!finite (v)) {
902  v = 0.0;
903  }
904  return v;
905 }
906 
907 /* PACKED-DECIMAL */
908 
909 static int
911 {
912  unsigned char *p;
913 
915  return 0;
916  }
917  p = f->data + f->size - 1;
918  return ((*p & 0x0FU) == 0x0DU) ? -1 : 1;
919 }
920 
921 #if 0 /* RXWRXW - Buggy */
922 static void
923 cob_complement_packed (cob_field *f)
924 {
925  unsigned char *p;
926  int ndigs;
927  int tval;
928  int carry = 0;
929  unsigned int msn;
930 
931  ndigs = COB_FIELD_DIGITS(f) - COB_FIELD_SCALE(f);
932  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
933  msn = COB_FIELD_SCALE(f) % 2;
934  } else {
935  msn = 1 - (COB_FIELD_SCALE(f) % 2);
936  }
937 
938  p = f->data + (ndigs / 2) - (1 - msn);
939  while (ndigs--) {
940  if (!msn) {
941  tval = *p & 0x0F;
942  } else {
943  tval = (*p & 0xF0) >> 4;
944  }
945  tval += carry;
946  if (tval > 0) {
947  carry = 1;
948  tval= 10 - tval;
949  } else {
950  carry = 0;
951  }
952  if (!msn) {
953  *p = (*p & 0xF0) | tval;
954  msn = 1;
955  } else {
956  *p = (*p & 0x0F) | (tval << 4);
957  msn = 0;
958  p--;
959  }
960  }
961 }
962 
963 static int
964 cob_add_packed (cob_field *f, int val, const int opt)
965 {
966  unsigned char *p;
967  int sign;
968  int ndigs;
969  int tval;
970  int carry = 0;
971  unsigned int msn;
972  unsigned int subtr = 0;
973  unsigned int zeroes = 0;
974  unsigned int origdigs;
975  unsigned char savedata[256];
976 
977  ndigs = COB_FIELD_DIGITS(f) - COB_FIELD_SCALE(f);
978  if (ndigs <= 0) {
979  return 0;
980  }
981 
982  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
983  memcpy (savedata, f->data, f->size);
984  }
985 
986  sign = cob_packed_get_sign (f);
987 
988  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
989  msn = COB_FIELD_SCALE(f) % 2;
990  } else {
991  msn = 1 - (COB_FIELD_SCALE(f) % 2);
992  }
993 
994  /* -x +v = -(x - v), -x -v = -(x + v) */
995  if (sign < 0) {
996  val = -val;
997  }
998  if (val < 0) {
999  val = -val;
1000  subtr = 1;
1001  }
1002  p = f->data + (ndigs / 2) - (1 - msn);
1003  origdigs = ndigs;
1004  while (ndigs--) {
1005  if (val) {
1006  carry += (val % 10);
1007  val /= 10;
1008  }
1009  if (!msn) {
1010  tval = *p & 0x0F;
1011  } else {
1012  tval = (*p & 0xF0) >> 4;
1013  }
1014  if (subtr) {
1015  tval -= carry;
1016  if (tval < 0) {
1017  tval += 10;
1018  carry = 1;
1019  } else {
1020  carry = 0;
1021  }
1022  } else {
1023  tval += carry;
1024  if (tval > 9) {
1025  tval = (tval + 6) & 0x0F;
1026  carry = 1;
1027  } else {
1028  carry = 0;
1029  }
1030  }
1031  if (tval == 0) {
1032  zeroes++;
1033  }
1034  if (!msn) {
1035  *p = (*p & 0xF0) | tval;
1036  msn = 1;
1037  } else {
1038  *p = (*p & 0x0F) | (tval << 4);
1039  msn = 0;
1040  p--;
1041  }
1042  }
1043  if (sign) {
1044  p = f->data + f->size - 1;
1045  if (origdigs == zeroes) {
1046  *p = (*p & 0xF0) | 0x0C;
1047  } else if (subtr && carry) {
1048  cob_complement_packed (f);
1049  sign = -sign;
1050  if (sign < 0) {
1051  *p = (*p & 0xF0) | 0x0D;
1052  } else {
1053  *p = (*p & 0xF0) | 0x0C;
1054  }
1055  }
1056  } else if (subtr && carry) {
1057  cob_complement_packed (f);
1058  }
1059  if (opt && (carry || val)) {
1060  /* Overflow */
1062  /* If we need to throw an exception */
1063  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
1064  memcpy (f->data, savedata, f->size);
1065  return cobglobptr->cob_exception_code;
1066  }
1067  }
1068  return 0;
1069 }
1070 #endif
1071 
1072 void
1074 {
1075  memset (f->data, 0, f->size);
1076  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
1077  return;
1078  }
1079  if (!COB_FIELD_HAVE_SIGN (f)) {
1080  *(f->data + f->size - 1) = 0x0F;
1081  } else {
1082  *(f->data + f->size - 1) = 0x0C;
1083  }
1084 }
1085 
1086 static void
1088 {
1089  unsigned char *p;
1090  unsigned char *endp;
1091  int digits;
1092  int sign;
1093  int nibtest;
1094  unsigned int byteval;
1095  unsigned int nonzero;
1096 
1097  p = f->data;
1098  digits = COB_FIELD_DIGITS (f);
1099 #if 0 /* RXWRXW - P Fix */
1100  if (digits > (f->size * 2) - 1) {
1101  digits = (f->size * 2) - 1;
1102  }
1103 #endif
1104  sign = cob_packed_get_sign (f);
1105 
1107  endp = f->data + f->size;
1108  nibtest = 1;
1109  } else {
1110  endp = f->data + f->size - 1;
1111  nibtest = 0;
1112  }
1113 
1114  byteval = 0;
1115  if (digits % 2 == nibtest) {
1116  byteval = *p & 0x0FU;
1117  p++;
1118  }
1119  mpz_set_ui (d->value, (cob_uli_t)byteval);
1120  nonzero = !!byteval;
1121 
1122  for (; p < endp; p++) {
1123  if (nonzero) {
1124  mpz_mul_ui (d->value, d->value, 100UL);
1125  }
1126  if (*p) {
1127  mpz_add_ui (d->value, d->value,
1128  (cob_uli_t)((*p >> 4U) * 10U) + (*p & 0x0FU));
1129  nonzero = 1;
1130  }
1131  }
1132 
1133  if (!nibtest) {
1134  if (nonzero) {
1135  mpz_mul_ui (d->value, d->value, 10UL);
1136  }
1137  mpz_add_ui (d->value, d->value, (cob_uli_t)(*p >> 4U));
1138  }
1139 
1140  if (sign < 0) {
1141  mpz_neg (d->value, d->value);
1142  }
1143  d->scale = COB_FIELD_SCALE(f);
1144 }
1145 
1146 static int
1148 {
1149  unsigned char *data;
1150  unsigned char *p;
1151  unsigned char *q;
1152  char *mza;
1153  size_t size;
1154  size_t n;
1155  size_t i;
1156  int diff;
1157  int sign;
1158  int digits;
1159  unsigned int x;
1160 
1161 #if 0 /* RXWRXW stack */
1162  char buff[1024];
1163 #endif
1164 
1165  /* Build string */
1166  sign = mpz_sgn (d->value);
1167  if (!sign) {
1168  /* Value is 0 */
1169  cob_set_packed_zero (f);
1170  return 0;
1171  }
1172  if (sign < 0) {
1173  mpz_abs (d->value, d->value);
1174  }
1175 
1176 #if 0 /* RXWRXW stack */
1177  if (unlikely(mpz_sizeinbase (d->value, 10) > sizeof(buff) - 1)) {
1178 #endif
1179  mza = mpz_get_str (NULL, 10, d->value);
1180 #if 0 /* RXWRXW stack */
1181  } else {
1182  mza = buff;
1183  (void)mpz_get_str (buff, 10, d->value);
1184  }
1185 #endif
1186  size = strlen (mza);
1187 
1188  /* Store number */
1189  data = f->data;
1190  digits = COB_FIELD_DIGITS (f);
1191 #if 0 /* RXWRXW - P Fix */
1192  if (digits > (f->size * 2) - 1) {
1193  digits = (f->size * 2) - 1;
1194  }
1195 #endif
1196  q = (unsigned char *)mza;
1197  diff = (int)(digits - size);
1198  if (diff < 0) {
1199  /* Overflow */
1201 
1202  /* If the statement has SIZE ERROR
1203  then throw an exception */
1204  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
1205 #if 0 /* RXWRXW stack */
1206  if (unlikely(mza != buff)) {
1207 #endif
1208  cob_gmp_free(mza);
1209 
1210 #if 0 /* RXWRXW stack */
1211  }
1212 #endif
1213  return cobglobptr->cob_exception_code;
1214  }
1215  q += size - digits;
1216  size = digits;
1217  }
1218  memset (data, 0, f->size);
1219  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
1220  p = data + ((digits - 1) / 2) - ((size - 1) / 2);
1221  diff = (int)(size % 2);
1222  } else {
1223  p = data + (digits / 2) - (size / 2);
1224  diff = 1 - (int)(size % 2);
1225  }
1226  for (i = diff, n = 0; i < size + diff; i++, n++) {
1227  x = COB_D2I (q[n]);
1228  if (i % 2 == 0) {
1229  *p = x << 4;
1230  } else {
1231  *p++ |= x;
1232  }
1233  }
1234 
1235 #if 0 /* RXWRXW stack */
1236  if (unlikely(mza != buff)) {
1237 #endif
1238  cob_gmp_free(mza);
1239 
1240 #if 0 /* RXWRXW stack */
1241  }
1242 #endif
1243 
1244  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
1245  return 0;
1246  }
1247 
1248  p = f->data + f->size - 1;
1249  if (!COB_FIELD_HAVE_SIGN (f)) {
1250  *p = (*p & 0xF0U) | 0x0FU;
1251  } else if (sign < 0) {
1252  *p = (*p & 0xF0U) | 0x0DU;
1253  } else {
1254  *p = (*p & 0xF0U) | 0x0CU;
1255  }
1256 
1257  return 0;
1258 }
1259 
1260 void
1261 cob_set_packed_int (cob_field *f, const int val)
1262 {
1263  unsigned char *p;
1264  size_t sign = 0;
1265  cob_u32_t n;
1266 
1267  if (!val) {
1268  cob_set_packed_zero (f);
1269  return;
1270  }
1271  if (val < 0) {
1272  n = (cob_u32_t)-val;
1273  sign = 1;
1274  } else {
1275  n = (cob_u32_t)val;
1276  }
1277  memset (f->data, 0, f->size);
1278  p = f->data + f->size - 1;
1279  if (!COB_FIELD_NO_SIGN_NIBBLE (f)) {
1280  *p = (n % 10) << 4;
1281  if (!COB_FIELD_HAVE_SIGN (f)) {
1282  *p |= 0x0FU;
1283  } else if (sign) {
1284  *p |= 0x0DU;
1285  } else {
1286  *p |= 0x0CU;
1287  }
1288  n /= 10;
1289  p--;
1290  }
1291  for (; n && p >= f->data; n /= 100, p--) {
1292  *p = packed_bytes[n % 100];
1293  }
1294  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
1295  if ((COB_FIELD_DIGITS(f) % 2) == 1) {
1296  *(f->data) &= 0x0FU;
1297  }
1298  return;
1299  }
1300  if ((COB_FIELD_DIGITS(f) % 2) == 0) {
1301  *(f->data) &= 0x0FU;
1302  }
1303 }
1304 
1305 /* DISPLAY */
1306 
1307 static void
1309 {
1310  unsigned char *data;
1311  unsigned char *p;
1312  size_t size;
1313  int sign;
1314  cob_uli_t n;
1315 
1316  data = COB_FIELD_DATA (f);
1317  size = COB_FIELD_SIZE (f);
1318  if (unlikely(*data == 255)) {
1319  mpz_ui_pow_ui (d->value, 10UL, (cob_uli_t)size);
1320  d->scale = COB_FIELD_SCALE(f);
1321  return;
1322  }
1323  if (unlikely(*data == 0)) {
1324  mpz_ui_pow_ui (d->value, 10UL, (cob_uli_t)size);
1325  mpz_neg (d->value, d->value);
1326  d->scale = COB_FIELD_SCALE(f);
1327  return;
1328  }
1329  sign = COB_GET_SIGN (f);
1330  /* Skip leading zeros (also invalid space/low-value) */
1331  while (size > 1 && (*data & 0x0FU) == 0) {
1332  size--;
1333  data++;
1334  }
1335 
1336  /* Set value */
1337  n = 0;
1338 
1339 #ifdef COB_LI_IS_LL
1340  if (size < 20) {
1341 #else
1342  if (size < 10) {
1343 #endif
1344  while (size--) {
1345  if (n) {
1346  n *= 10;
1347  }
1348  n += COB_D2I (*data);
1349  data++;
1350  }
1351  mpz_set_ui (d->value, n);
1352  } else {
1353  p = cob_fast_malloc (size + 1U);
1354  for (; n < size; ++n) {
1355  p[n] = (data[n] & 0x0FU) + '0';
1356  }
1357  p[size] = 0;
1358  mpz_set_str (d->value, (char *)p, 10);
1359  cob_free (p);
1360  }
1361 
1362  /* Set sign and scale */
1363  if (sign < 0 && mpz_sgn (d->value)) {
1364  mpz_neg (d->value, d->value);
1365  }
1366  d->scale = COB_FIELD_SCALE(f);
1367  COB_PUT_SIGN (f, sign);
1368 }
1369 
1370 static int
1372 {
1373  unsigned char *data;
1374  char *p;
1375  size_t size;
1376  int diff;
1377  int sign;
1378 
1379  data = COB_FIELD_DATA (f);
1380  /* Build string */
1381  sign = mpz_sgn (d->value);
1382  if (!sign) {
1383  /* Value is 0 */
1384  memset (data, '0', COB_FIELD_SIZE (f));
1385  COB_PUT_SIGN (f, sign);
1386  return 0;
1387  }
1388  if (sign < 0) {
1389  mpz_abs (d->value, d->value);
1390  }
1391  p = mpz_get_str (NULL, 10, d->value);
1392  size = strlen (p);
1393 
1394  /* Store number */
1395  diff = (int)(COB_FIELD_SIZE (f) - size);
1396  if (unlikely(diff < 0)) {
1397  /* Overflow */
1399 
1400  /* If the statement has ON SIZE ERROR or NOT ON SIZE ERROR,
1401  then throw an exception */
1402  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
1403  cob_gmp_free(p);
1404  return cobglobptr->cob_exception_code;
1405  }
1406 
1407  /* Othersize, truncate digits */
1408  memcpy (data, p - diff, COB_FIELD_SIZE (f));
1409  } else {
1410  /* No overflow */
1411  memset (data, '0', (size_t)diff);
1412  memcpy (data + diff, p, size);
1413  }
1414 
1415  cob_gmp_free(p);
1416  COB_PUT_SIGN (f, sign);
1417 
1418  return 0;
1419 }
1420 
1421 /* BINARY */
1422 
1423 static void
1425 {
1426 #ifdef COB_EXPERIMENTAL
1427 #if 1 /* RXWRXW - set_usll */
1428  size_t size;
1429  size_t sizeb;
1430  size_t idx;
1431  int order;
1432  unsigned char buff[COB_MAX_BINARY + 1];
1433 
1434  size = f->size;
1435 #ifndef WORDS_BIGENDIAN
1436  if (!COB_FIELD_BINARY_SWAP (f)) {
1437  sizeb = size - 1;
1438  order = -1;
1439  } else {
1440  sizeb = 0;
1441  order = 1;
1442  }
1443 #else
1444  sizeb = 0;
1445  order = 1;
1446 #endif
1447  if (COB_FIELD_HAVE_SIGN (f) && (f->data[sizeb] & 0x80U)) {
1448  for (idx = 0; idx < size; ++idx) {
1449  buff[idx] = ~f->data[idx];
1450  }
1451  mpz_import (d->value, 1, order, size, order, 0, buff);
1452  mpz_com (d->value, d->value);
1453  } else {
1454  mpz_import (d->value, 1, order, size, order, 0, f->data);
1455  }
1456 
1457 #else
1458  if (COB_FIELD_HAVE_SIGN (f)) {
1459  mpz_set_sll (d->value, cob_binary_get_sint64 (f));
1460  } else {
1461  mpz_set_ull (d->value, cob_binary_get_uint64 (f));
1462  }
1463 #endif
1464 
1465 #elif defined(COB_LI_IS_LL)
1466  if (COB_FIELD_HAVE_SIGN (f)) {
1467  mpz_set_si (d->value, cob_binary_get_sint64 (f));
1468  } else {
1469  mpz_set_ui (d->value, cob_binary_get_uint64 (f));
1470  }
1471 #else
1472  cob_u64_t uval;
1473  cob_s64_t val;
1474  size_t negative;
1475 
1476  if (f->size <= 4) {
1477  if (COB_FIELD_HAVE_SIGN (f)) {
1478  mpz_set_si (d->value, (cob_sli_t)cob_binary_get_sint64 (f));
1479  } else {
1480  mpz_set_ui (d->value, (cob_uli_t) cob_binary_get_uint64 (f));
1481  }
1482  } else {
1483  negative = 0;
1484  if (COB_FIELD_HAVE_SIGN (f)) {
1485  val = cob_binary_get_sint64 (f);
1486  if (val < 0) {
1487  negative = 1;
1488  uval = (cob_u64_t)-val;
1489  } else {
1490  uval = (cob_u64_t)val;
1491  }
1492  } else {
1493  uval = cob_binary_get_uint64 (f);
1494  }
1495  mpz_set_ui (d->value, (cob_uli_t)(uval >> 32));
1496  mpz_mul_2exp (d->value, d->value, 32);
1497  mpz_add_ui (d->value, d->value, (cob_uli_t)(uval & 0xFFFFFFFFU));
1498  if (negative) {
1499  mpz_neg (d->value, d->value);
1500  }
1501  }
1502 #endif
1503  d->scale = COB_FIELD_SCALE(f);
1504 }
1505 
1506 static int
1508 {
1509  size_t overflow;
1510  size_t sign;
1511  size_t bitnum;
1512  size_t digits;
1513 
1514 #if !defined(COB_EXPERIMENTAL) && !defined(COB_LI_IS_LL)
1515  cob_s64_t llval;
1516  cob_u64_t ullval;
1517  unsigned int lo;
1518 #endif
1519 
1520  if (unlikely(mpz_size (d->value) == 0)) {
1521  memset (f->data, 0, f->size);
1522  return 0;
1523  }
1524  overflow = 0;
1525  digits = COB_FIELD_DIGITS(f);
1526  if (COB_FIELD_HAVE_SIGN (f)) {
1527  sign = 1;
1528  } else {
1529  sign = 0;
1530  if (mpz_sgn (d->value) < 0) {
1531  mpz_abs (d->value, d->value);
1532  }
1533  }
1534  bitnum = (f->size * 8) - sign;
1535  if (unlikely(mpz_sizeinbase (d->value, 2) > bitnum)) {
1536  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
1537  goto overflow;
1538  }
1539  overflow = 1;
1540  /* Check if truncation to PIC digits is needed */
1541  if (opt & COB_STORE_TRUNC_ON_OVERFLOW) {
1542  mpz_tdiv_r (d->value, d->value, cob_mpze10[digits]);
1543  } else {
1544 #if 0 /* RXWRXW - Fdiv sign */
1545  mpz_fdiv_r_2exp (d->value, d->value, (f->size * 8) - sign);
1546 #endif
1547  mpz_fdiv_r_2exp (d->value, d->value, (f->size * 8));
1548  }
1549  } else if (opt && COB_FIELD_BINARY_TRUNC (f)) {
1550  if (mpz_cmpabs (d->value, cob_mpze10[digits]) >= 0) {
1551  /* Overflow */
1552  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
1553  goto overflow;
1554  }
1555  overflow = 1;
1556  /* Check if truncation to PIC digits is needed */
1557  if (opt & COB_STORE_TRUNC_ON_OVERFLOW) {
1558  mpz_tdiv_r (d->value, d->value,
1559  cob_mpze10[digits]);
1560  } else {
1561  mpz_fdiv_r_2exp (d->value, d->value, (f->size * 8));
1562  }
1563  }
1564  }
1565 #ifdef COB_LI_IS_LL
1566  if (!sign || (overflow && !(opt & COB_STORE_TRUNC_ON_OVERFLOW))) {
1567  cob_binary_set_uint64 (f, mpz_get_ui (d->value));
1568  } else {
1569  cob_binary_set_int64 (f, mpz_get_si (d->value));
1570  }
1571 #elif defined(COB_EXPERIMENTAL)
1572  if (!sign || (overflow && !(opt & COB_STORE_TRUNC_ON_OVERFLOW))) {
1573  cob_binary_set_uint64 (f, mpz_get_ull (d->value));
1574  } else {
1575  cob_binary_set_int64 (f, mpz_get_sll (d->value));
1576  }
1577 #else
1578  if (f->size <= 4) {
1579  if (!sign || (overflow && !(opt & COB_STORE_TRUNC_ON_OVERFLOW))) {
1580  cob_binary_set_uint64 (f, (cob_u64_t)mpz_get_ui (d->value));
1581  } else {
1582  cob_binary_set_int64 (f, (cob_s64_t)mpz_get_si (d->value));
1583  }
1584  } else {
1585  mpz_fdiv_r_2exp (cob_mpzt, d->value, 32);
1586  mpz_fdiv_q_2exp (d->value, d->value, 32);
1587  lo = mpz_get_ui (cob_mpzt);
1588 
1589  if (!sign || (overflow && !(opt & COB_STORE_TRUNC_ON_OVERFLOW))) {
1590  ullval = mpz_get_ui (d->value);
1591  ullval = (ullval << 32) | lo;
1592  cob_binary_set_uint64 (f, ullval);
1593  } else {
1594  llval = mpz_get_si (d->value);
1595  llval = (llval << 32) | lo;
1596  cob_binary_set_int64 (f, llval);
1597  }
1598  }
1599 #endif
1600  if (!overflow) {
1601  return 0;
1602  }
1603 
1604 overflow:
1606  return cobglobptr->cob_exception_code;
1607 }
1608 
1609 /* General field */
1610 
1611 void
1613 {
1614  union {
1615  double dval;
1616  float fval;
1617  } uval;
1618 
1619  switch (COB_FIELD_TYPE (f)) {
1621  cob_decimal_set_binary (d, f);
1622  break;
1624  cob_decimal_set_packed (d, f);
1625  break;
1627  memcpy ((void *)&uval.fval, f->data, sizeof(float));
1628  cob_decimal_set_double (d, (double)uval.fval);
1629  break;
1631  memcpy ((void *)&uval.dval, f->data, sizeof(double));
1632  cob_decimal_set_double (d, uval.dval);
1633  break;
1636  break;
1639  break;
1640  default:
1641  cob_decimal_set_display (d, f);
1642  break;
1643  }
1644 }
1645 
1646 void
1647 cob_print_ieeedec (const cob_field *f, FILE *fp)
1648 {
1649  union {
1650  double dval;
1651  float fval;
1652  } uval;
1653 
1654  switch (COB_FIELD_TYPE (f)) {
1656  cob_decimal_set_ieee64dec (&cob_d3, f);
1657  break;
1659  cob_decimal_set_ieee128dec (&cob_d3, f);
1660  break;
1662  memcpy ((void *)&uval.fval, f->data, sizeof(float));
1663  cob_decimal_set_double (&cob_d3, (double)uval.fval);
1664  break;
1666  memcpy ((void *)&uval.dval, f->data, sizeof(double));
1667  cob_decimal_set_double (&cob_d3, uval.dval);
1668  break;
1669  default:
1670  return;
1671  }
1672  cob_decimal_print (&cob_d3, fp);
1673 }
1674 
1675 void
1676 cob_print_realbin (const cob_field *f, FILE *fp, const int size)
1677 {
1678  union {
1679  cob_u64_t uval;
1680  cob_s64_t val;
1681  } llval;
1682 
1683  if (COB_FIELD_HAVE_SIGN (f)) {
1684  llval.val = cob_binary_get_sint64 (f);
1685  fprintf (fp, CB_FMT_PLLD, size, size, llval.val);
1686  return;
1687  }
1688  llval.uval = cob_binary_get_uint64 (f);
1689  fprintf (fp, CB_FMT_PLLU, size, size, llval.uval);
1690 }
1691 
1692 static void
1694 {
1695  cob_uli_t adj;
1696  int sign;
1697  int scale;
1698 
1699  sign = mpz_sgn (d->value);
1700  /* Returns 0 when value is 0 */
1701  if (!sign) {
1702  return;
1703  }
1704  scale = COB_FIELD_SCALE(f);
1705  if (scale >= d->scale) {
1706  return;
1707  }
1708 
1709  switch (opt & ~(COB_STORE_MASK)) {
1710  case COB_STORE_TRUNCATION:
1711  return;
1712  case COB_STORE_PROHIBITED:
1714  return;
1716  adj = d->scale - scale;
1717  mpz_ui_pow_ui (cob_mpzt, 10UL, adj);
1718  mpz_tdiv_r (cob_mpzt2, d->value, cob_mpzt);
1719  if (mpz_sgn (cob_mpzt2)) {
1720  /* Not exact number */
1721  if (sign < 0) {
1722  mpz_sub (d->value, d->value, cob_mpzt);
1723  } else {
1724  mpz_add (d->value, d->value, cob_mpzt);
1725  }
1726  }
1727  return;
1729  adj = d->scale - scale - 1;
1730  mpz_ui_pow_ui (cob_mpzt, 10UL, adj);
1731  mpz_mul_ui (cob_mpzt, cob_mpzt, 5UL);
1732  mpz_tdiv_r (cob_mpzt2, d->value, cob_mpzt);
1733  shift_decimal (d, scale - d->scale + 1);
1734  if (!mpz_sgn (cob_mpzt2)) {
1735  return;
1736  }
1737  if (sign > 0) {
1738  mpz_add_ui (d->value, d->value, 5UL);
1739  } else {
1740  mpz_sub_ui (d->value, d->value, 5UL);
1741  }
1742  return;
1744  adj = d->scale - scale;
1745  mpz_ui_pow_ui (cob_mpzt, 10UL, adj);
1746  mpz_tdiv_r (cob_mpzt2, d->value, cob_mpzt);
1747  if (mpz_sgn (cob_mpzt2)) {
1748  /* Not exact number */
1749  if (sign > 0) {
1750  mpz_add (d->value, d->value, cob_mpzt);
1751  }
1752  }
1753  return;
1755  adj = d->scale - scale;
1756  mpz_ui_pow_ui (cob_mpzt, 10UL, adj);
1757  mpz_tdiv_r (cob_mpzt2, d->value, cob_mpzt);
1758  if (mpz_sgn (cob_mpzt2)) {
1759  /* Not exact number */
1760  if (sign < 0) {
1761  mpz_sub (d->value, d->value, cob_mpzt);
1762  }
1763  }
1764  return;
1765  case COB_STORE_NEAR_EVEN:
1766  adj = d->scale - scale - 1;
1767  mpz_ui_pow_ui (cob_mpzt, 10UL, adj);
1768  mpz_mul_ui (cob_mpzt, cob_mpzt, 5UL);
1769  mpz_tdiv_r (cob_mpzt, d->value, cob_mpzt);
1770  shift_decimal (d, scale - d->scale + 1);
1771  if (!mpz_sgn (cob_mpzt)) {
1772  adj = mpz_tdiv_ui (d->value, 100UL);
1773  switch (adj) {
1774  case 5:
1775  case 25:
1776  case 45:
1777  case 65:
1778  case 85:
1779  return;
1780  }
1781  }
1782  if (sign > 0) {
1783  mpz_add_ui (d->value, d->value, 5UL);
1784  } else {
1785  mpz_sub_ui (d->value, d->value, 5UL);
1786  }
1787  return;
1789  default:
1790  shift_decimal (d, scale - d->scale + 1);
1791  if (sign > 0) {
1792  mpz_add_ui (d->value, d->value, 5UL);
1793  } else {
1794  mpz_sub_ui (d->value, d->value, 5UL);
1795  }
1796  return;
1797  }
1798 }
1799 
1800 int
1802 {
1803  cob_field temp;
1804  cob_field_attr attr;
1805  union {
1806  double val;
1807  float fval;
1808  } uval;
1809 
1810  if (unlikely(d->scale == COB_DECIMAL_NAN)) {
1812  return cobglobptr->cob_exception_code;
1813  }
1814 
1815  /* work copy */
1816  if (d != &cob_d1) {
1817  mpz_set (cob_d1.value, d->value);
1818  cob_d1.scale = d->scale;
1819  d = &cob_d1;
1820  }
1821 
1822 #if 0 /* RXWRXW - Round FP */
1823  if (!COB_FIELD_IS_FP(f)) {
1824 #endif
1825  /* Rounding */
1826  if ((opt & COB_STORE_ROUND)) {
1827  cob_decimal_do_round (d, f, opt);
1828  }
1829  /* Append or truncate decimal digits */
1830  shift_decimal (d, COB_FIELD_SCALE(f) - d->scale);
1831 #if 0 /* RXWRXW - Round FP */
1832  }
1833 #endif
1834 
1835  /* Store number */
1836  switch (COB_FIELD_TYPE (f)) {
1838  return cob_decimal_get_binary (d, f, opt);
1840  return cob_decimal_get_display (d, f, opt);
1842  return cob_decimal_get_packed (d, f, opt);
1844  uval.fval = (float) cob_decimal_get_double (d);
1845  memcpy (f->data, &uval.fval, sizeof (float));
1846  return 0;
1848  uval.val = cob_decimal_get_double (d);
1849  memcpy (f->data, &uval.val, sizeof (double));
1850  return 0;
1852  return cob_decimal_get_ieee64dec (d, f, opt);
1854  return cob_decimal_get_ieee128dec (d, f, opt);
1855  default:
1856  break;
1857  }
1860  temp.size = COB_FIELD_DIGITS(f);
1861  temp.data = cob_malloc (COB_FIELD_DIGITS(f));
1862  temp.attr = &attr;
1863  if (cob_decimal_get_display (d, &temp, opt) == 0) {
1864  cob_move (&temp, f);
1865  cob_free (temp.data);
1866  return 0;
1867  }
1868  cob_free (temp.data);
1869  return cobglobptr->cob_exception_code;
1870 }
1871 
1872 /* Decimal arithmetic */
1873 
1874 void
1876 {
1877  DECIMAL_CHECK (d1, d2);
1878  align_decimal (d1, d2);
1879  mpz_add (d1->value, d1->value, d2->value);
1880 }
1881 
1882 void
1884 {
1885  DECIMAL_CHECK (d1, d2);
1886  align_decimal (d1, d2);
1887  mpz_sub (d1->value, d1->value, d2->value);
1888 }
1889 
1890 void
1892 {
1893  DECIMAL_CHECK (d1, d2);
1894  d1->scale += d2->scale;
1895  mpz_mul (d1->value, d1->value, d2->value);
1896 }
1897 
1898 void
1900 {
1901  DECIMAL_CHECK (d1, d2);
1902 
1903  /* Check for division by zero */
1904  if (unlikely(mpz_sgn (d2->value) == 0)) {
1905  d1->scale = COB_DECIMAL_NAN;
1907  return;
1908  }
1909  if (unlikely(mpz_sgn (d1->value) == 0)) {
1910  d1->scale = 0;
1911  return;
1912  }
1913  d1->scale -= d2->scale;
1914  shift_decimal (d1, COB_MAX_DIGITS + ((d1->scale < 0) ? -d1->scale : 0));
1915 #if 0 /* RXWRXW - cdiv */
1916  mpz_cdiv_q (d1->value, d1->value, d2->value);
1917 #endif
1918  mpz_tdiv_q (d1->value, d1->value, d2->value);
1919 }
1920 
1921 int
1923 {
1924  align_decimal (d1, d2);
1925  return mpz_cmp (d1->value, d2->value);
1926 }
1927 
1928 /* Convenience functions */
1929 
1930 void
1931 cob_add (cob_field *f1, cob_field *f2, const int opt)
1932 {
1933  cob_decimal_set_field (&cob_d1, f1);
1934  cob_decimal_set_field (&cob_d2, f2);
1935  cob_decimal_add (&cob_d1, &cob_d2);
1936  (void)cob_decimal_get_field (&cob_d1, f1, opt);
1937 }
1938 
1939 void
1940 cob_sub (cob_field *f1, cob_field *f2, const int opt)
1941 {
1942  cob_decimal_set_field (&cob_d1, f1);
1943  cob_decimal_set_field (&cob_d2, f2);
1944  cob_decimal_sub (&cob_d1, &cob_d2);
1945  (void)cob_decimal_get_field (&cob_d1, f1, opt);
1946 }
1947 
1948 void
1949 cob_mul (cob_field *f1, cob_field *f2, const int opt)
1950 {
1951  cob_decimal_set_field (&cob_d1, f1);
1952  cob_decimal_set_field (&cob_d2, f2);
1953  cob_decimal_mul (&cob_d1, &cob_d2);
1954  (void)cob_decimal_get_field (&cob_d1, f1, opt);
1955 }
1956 
1957 void
1958 cob_div (cob_field *f1, cob_field *f2, const int opt)
1959 {
1960  cob_decimal_set_field (&cob_d1, f1);
1961  cob_decimal_set_field (&cob_d2, f2);
1962  cob_decimal_div (&cob_d1, &cob_d2);
1963  (void)cob_decimal_get_field (&cob_d1, f1, opt);
1964 }
1965 
1966 void
1967 cob_div_quotient (cob_field *dividend, cob_field *divisor,
1968  cob_field *quotient, const int opt)
1969 {
1970  /* Note that cob_div_quotient and cob_div_remainder must remain */
1971  /* separate because of COBOL rules. The quotient must be fully */
1972  /* evaluated before the remainder item is evaluated */
1973  /* eg. DIVIDE A BY B GIVING Z REMAINDER FLD (Z). */
1974 
1975  cob_decimal_set_field (&cob_d1, dividend);
1976  cob_decimal_set_field (&cob_d2, divisor);
1977  cob_decimal_set (&cob_d_remainder, &cob_d1);
1978 
1979  /* Compute quotient */
1980  cob_decimal_div (&cob_d1, &cob_d2);
1981  /* Check divide by zero - Exception is set in cob_decimal_div */
1982  if (cob_d1.scale == COB_DECIMAL_NAN) {
1983  /* Forces an early return from cob_div_remainder */
1984  cob_d_remainder.scale = COB_DECIMAL_NAN;
1985  return;
1986  }
1987 
1988  /* Set quotient */
1989  cob_decimal_set (&cob_d3, &cob_d1);
1990  (void)cob_decimal_get_field (&cob_d1, quotient, opt);
1991 
1992  /* Truncate digits from the quotient */
1993  shift_decimal (&cob_d3, COB_FIELD_SCALE(quotient) - cob_d3.scale);
1994 
1995  /* Compute remainder */
1996  cob_decimal_mul (&cob_d3, &cob_d2);
1997  cob_decimal_sub (&cob_d_remainder, &cob_d3);
1998 }
1999 
2000 void
2001 cob_div_remainder (cob_field *fld_remainder, const int opt)
2002 {
2003  (void)cob_decimal_get_field (&cob_d_remainder, fld_remainder, opt);
2004 }
2005 
2006 void
2007 cob_decimal_setget_fld (cob_field *src, cob_field *dst, const int opt)
2008 {
2009  cob_decimal_set_field (&cob_d1, src);
2010  (void)cob_decimal_get_field (&cob_d1, dst, opt);
2011 }
2012 
2013 #if 0 /* RXWRXW - Buggy */
2014 
2015 /* Optimized arithmetic for DISPLAY */
2016 
2017 static int
2018 display_add_int (unsigned char *data, const size_t size, int n, const int opt)
2019 {
2020  unsigned char *sp;
2021  size_t carry = 0;
2022  int i;
2023  int is;
2024 
2025  sp = data + size;
2026  while (n > 0) {
2027  i = n % 10;
2028  n /= 10;
2029 
2030  /* Check for overflow */
2031  if (unlikely(--sp < data)) {
2032  return opt;
2033  }
2034 
2035  /* Perform addition */
2036  is = (*sp & 0x0F) + i + carry;
2037  if (is > 9) {
2038  carry = 1;
2039  *sp = '0' + ((is + 6) & 0x0F);
2040  } else {
2041  carry = 0;
2042  *sp = '0' + is;
2043  }
2044  }
2045  if (carry == 0) {
2046  return 0;
2047  }
2048 
2049  /* Carry up */
2050  while (--sp >= data) {
2051  if ((*sp += 1) <= (unsigned char)'9') {
2052  return 0;
2053  }
2054  *sp = '0';
2055  }
2056  return opt;
2057 }
2058 
2059 static int
2060 display_sub_int (unsigned char *data, const size_t size, int n, const int opt)
2061 {
2062  unsigned char *sp;
2063  size_t carry = 0;
2064  int i;
2065 
2066  COB_UNUSED (opt);
2067 
2068  sp = data + size;
2069  while (n > 0) {
2070  i = n % 10;
2071  n /= 10;
2072 
2073  /* Check for overflow */
2074  if (unlikely(--sp < data)) {
2075  return 1;
2076  }
2077 
2078 #if 0 /* RXWRXW - Garbage check */
2079  /* Correct garbage */
2080  *sp = (unsigned char)('0' + (*sp & 0x0F));
2081 #endif
2082  /* Perform subtraction */
2083  if ((*sp -= i + carry) < '0') {
2084  carry = 1;
2085  *sp += 10;
2086  } else {
2087  carry = 0;
2088  }
2089  }
2090  if (carry == 0) {
2091  return 0;
2092  }
2093 
2094  /* Carry up */
2095  while (--sp >= data) {
2096 #if 0 /* RXWRXW - Garbage check */
2097  /* Correct garbage */
2098  *sp = (unsigned char)('0' + (*sp & 0x0F));
2099 #endif
2100  if ((*sp -= 1) >= (unsigned char)'0') {
2101  return 0;
2102  }
2103  *sp = '9';
2104  }
2105  return 1;
2106 }
2107 
2108 static int
2109 cob_display_add_int (cob_field *f, int n, const int opt)
2110 {
2111  unsigned char *data;
2112  size_t osize;
2113  size_t size;
2114  size_t i;
2115  int scale;
2116  int sign;
2117  unsigned char tfield[256];
2118 
2119  data = COB_FIELD_DATA (f);
2120  size = COB_FIELD_SIZE (f);
2121  osize = size;
2122  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
2123  memcpy (tfield, data, size);
2124  }
2125  scale = COB_FIELD_SCALE (f);
2126  sign = COB_GET_SIGN (f);
2127  /* -x +v = -(x - v), -x -v = -(x + v) */
2128  if (sign < 0) {
2129  n = -n;
2130  }
2131 
2132  if (unlikely(scale < 0)) {
2133  /* PIC 9(n)P(m) */
2134  if (-scale < 10) {
2135  while (scale++) {
2136  n /= 10;
2137  }
2138  } else {
2139  n = 0;
2140  }
2141  scale = 0;
2142  if (n == 0) {
2143  return 0;
2144  }
2145  } else {
2146  /* PIC 9(n)V9(m) */
2147  size -= scale;
2148  if (!size) {
2149  COB_PUT_SIGN (f, sign);
2151  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
2152  return cobglobptr->cob_exception_code;
2153  }
2154  return 0;
2155  }
2156  }
2157 
2158  if (n > 0) {
2159  /* Add n to the field */
2160  if (display_add_int (data, size, n, opt) != 0) {
2161  /* Overflow */
2162  COB_PUT_SIGN (f, sign);
2164  /* If we need to restore */
2165  if (opt & COB_STORE_KEEP_ON_OVERFLOW) {
2166  memcpy (data, tfield, osize);
2167  return cobglobptr->cob_exception_code;
2168  }
2169  }
2170  } else if (n < 0) {
2171  /* Subtract n from the field */
2172  if (display_sub_int (data, size, -n, opt) != 0) {
2173  for (i = 0; i < size; ++i) {
2174  data[i] = COB_I2D (9 - COB_D2I (data[i]));
2175  }
2176  if (scale) {
2177  for (i = size; i < size + scale; ++i) {
2178  if (COB_D2I (data[i]) > 0) {
2179  data[i] = COB_I2D (10 - COB_D2I (data[i]));
2180  }
2181  }
2182  } else {
2183  (void)display_add_int (data, size, 1, 0);
2184  }
2185  sign = -sign;
2186  }
2187  }
2188 
2189  COB_PUT_SIGN (f, sign);
2190  return 0;
2191 }
2192 #endif /* Buggy */
2193 
2194 int
2195 cob_add_int (cob_field *f, const int n, const int opt)
2196 {
2197  int scale;
2198  int val;
2199 
2200  if (unlikely(n == 0)) {
2201  return 0;
2202  }
2203 #if 0 /* RXWRXW - Buggy */
2205  return cob_add_packed (f, n, opt);
2206  } else if (COB_FIELD_TYPE (f) == COB_TYPE_NUMERIC_DISPLAY) {
2207  return cob_display_add_int (f, n, opt);
2208  }
2209 #endif
2210 
2211  /* Not optimized */
2212  cob_decimal_set_field (&cob_d1, f);
2213 
2216  mpz_set_si (cob_d2.value, (cob_sli_t) n);
2217  cob_d2.scale = 0;
2218  mpz_add (cob_d1.value, cob_d1.value, cob_d2.value);
2219  return cob_decimal_get_field (&cob_d1, f, opt);
2220  }
2221  else {
2222  scale = COB_FIELD_SCALE (f);
2223  val = n;
2224  if (unlikely(scale < 0)) {
2225  /* PIC 9(n)P(m) */
2226  if (-scale < 10) {
2227  while (scale++) {
2228  val /= 10;
2229  }
2230  } else {
2231  val = 0;
2232  }
2233  scale = 0;
2234  if (!val) {
2235  return 0;
2236  }
2237  }
2238  mpz_set_si (cob_d2.value, (cob_sli_t)val);
2239  cob_d2.scale = 0;
2240  if (scale > 0) {
2241  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)scale);
2242  mpz_mul (cob_d2.value, cob_d2.value, cob_mexp);
2243  cob_d2.scale = cob_d1.scale;
2244  }
2245  mpz_add (cob_d1.value, cob_d1.value, cob_d2.value);
2246  return cob_decimal_get_field (&cob_d1, f, opt);
2247  }
2248 }
2249 
2250 int
2251 cob_sub_int (cob_field *f, const int n, const int opt)
2252 {
2253  return cob_add_int (f, -n, opt);
2254 }
2255 
2256 int
2257 cob_cmp_int (cob_field *f1, const int n)
2258 {
2259  cob_decimal_set_field (&cob_d1, f1);
2260  mpz_set_si (cob_d2.value, (cob_sli_t)n);
2261  cob_d2.scale = 0;
2262  return cob_decimal_cmp (&cob_d1, &cob_d2);
2263 }
2264 
2265 int
2266 cob_cmp_uint (cob_field *f1, const unsigned int n)
2267 {
2268  cob_decimal_set_field (&cob_d1, f1);
2269  mpz_set_ui (cob_d2.value, (cob_uli_t)n);
2270  cob_d2.scale = 0;
2271  return cob_decimal_cmp (&cob_d1, &cob_d2);
2272 }
2273 
2274 int
2276 {
2277 #ifdef COB_LI_IS_LL
2278  if (COB_FIELD_HAVE_SIGN(f1)) {
2279  mpz_set_si (cob_d2.value, (cob_sli_t)n);
2280  } else {
2281  mpz_set_ui (cob_d2.value, (cob_uli_t)n);
2282  }
2283 #else
2284  cob_u64_t uval;
2285  cob_u32_t negative;
2286 
2287  negative = 0;
2288  if (n < 0) {
2289  negative = 1;
2290  uval = (cob_u64_t)-n;
2291  } else {
2292  uval = (cob_u64_t)n;
2293  }
2294  mpz_set_ui (cob_d2.value, (cob_uli_t)(uval >> 32));
2295  mpz_mul_2exp (cob_d2.value, cob_d2.value, 32);
2296  mpz_add_ui (cob_d2.value, cob_d2.value, (cob_uli_t)(uval & 0xFFFFFFFFU));
2297  if (negative) {
2298  mpz_neg (cob_d2.value, cob_d2.value);
2299  }
2300 #endif
2301 
2302  cob_d2.scale = 0;
2303  cob_decimal_set_field (&cob_d1, f1);
2304  return cob_decimal_cmp (&cob_d1, &cob_d2);
2305 }
2306 
2307 #ifdef COB_FLOAT_DELTA
2308 #define TOLERANCE (double) COB_FLOAT_DELTA
2309 #else
2310 #define TOLERANCE (double) 0.0000001
2311 #endif
2312 #define FLOAT_EQ(x,y,t) (fabs(((x-y)/x)) < t)
2313 
2314 int
2316 {
2317  double d1,d2;
2318  float flt;
2320  memcpy(&flt,f1->data,sizeof(float));
2321  d1 = flt;
2322  } else if(COB_FIELD_TYPE (f1) == COB_TYPE_NUMERIC_DOUBLE) {
2323  memcpy(&d1,f1->data,sizeof(double));
2324  } else {
2325  cob_decimal_set_field (&cob_d1, f1);
2326  d1 = cob_decimal_get_double(&cob_d1);
2327  }
2329  memcpy(&flt,f2->data,sizeof(float));
2330  d2 = flt;
2331  } else if(COB_FIELD_TYPE (f2) == COB_TYPE_NUMERIC_DOUBLE) {
2332  memcpy(&d2,f2->data,sizeof(double));
2333  } else {
2334  cob_decimal_set_field (&cob_d1, f2);
2335  d2 = cob_decimal_get_double(&cob_d1);
2336  }
2337  if(d1 == d2)
2338  return 0;
2339  if(d1 != 0.0
2340  && FLOAT_EQ(d1,d2,TOLERANCE))
2341  return 0;
2342  if(d1 < d2)
2343  return -1;
2344  return 1;
2345 }
2346 
2347 int
2349 {
2354  return cob_cmp_float(f1,f2);
2355  }
2356  cob_decimal_set_field (&cob_d1, f1);
2357  cob_decimal_set_field (&cob_d2, f2);
2358  return cob_decimal_cmp (&cob_d1, &cob_d2);
2359 }
2360 
2361 int
2363 {
2364  unsigned char *p;
2365  cob_u64_t n;
2366  size_t size;
2367  size_t inc;
2368  int sign;
2369  unsigned char val1[20];
2370 
2371  sign = cob_packed_get_sign (f);
2372  /* Field positive, value negative */
2373  if (sign >= 0 && val < 0) {
2374  return 1;
2375  }
2376  /* Field negative, value positive */
2377  if (sign < 0 && val >= 0) {
2378  return -1;
2379  }
2380  /* Both positive or both negative */
2381  if (val < 0) {
2382  n = (cob_u64_t)-val;
2383  } else {
2384  n = (cob_u64_t)val;
2385  }
2386  inc = 0;
2387  p = f->data;
2388  for (size = 0; size < 20; size++) {
2389  if (size < 20 - f->size) {
2390  val1[size] = 0;
2391  } else {
2392  val1[size] = p[inc++];
2393  }
2394  }
2395  if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
2396  if ((COB_FIELD_DIGITS(f) % 2) == 1) {
2397  val1[20 - f->size] &= 0x0F;
2398  }
2399  } else {
2400  val1[19] &= 0xF0;
2401  if ((COB_FIELD_DIGITS(f) % 2) == 0) {
2402  val1[20 - f->size] &= 0x0F;
2403  }
2404  }
2405  if (n != last_packed_val) {
2406  last_packed_val = n;
2407  memset (packed_value, 0, sizeof(packed_value));
2408  if (n) {
2409  p = &packed_value[19];
2410  if (!COB_FIELD_NO_SIGN_NIBBLE (f)) {
2411  *p = (n % 10) << 4;
2412  p--;
2413  n /= 10;
2414  }
2415  for (; n;) {
2416  size = n % 100;
2417  *p = (unsigned char)((size % 10) | ((size / 10) << 4));
2418  n /= 100;
2419  p--;
2420  }
2421  }
2422  }
2423  for (size = 0; size < 20; size++) {
2424  if (val1[size] != packed_value[size]) {
2425  if (sign < 0) {
2426  return packed_value[size] - val1[size];
2427  } else {
2428  return val1[size] - packed_value[size];
2429  }
2430  }
2431  }
2432  return 0;
2433 }
2434 
2435 /* Numeric Display compares */
2436 
2437 #ifdef COB_EBCDIC_MACHINE
2438 static unsigned int
2439 cob_get_long_ascii_sign (const unsigned char *p, cob_s64_t *val)
2440 {
2441  switch (*p) {
2442  case 'p':
2443  return 1;
2444  case 'q':
2445  *val += 1;
2446  return 1;
2447  case 'r':
2448  *val += 2;
2449  return 1;
2450  case 's':
2451  *val += 3;
2452  return 1;
2453  case 't':
2454  *val += 4;
2455  return 1;
2456  case 'u':
2457  *val += 5;
2458  return 1;
2459  case 'v':
2460  *val += 6;
2461  return 1;
2462  case 'w':
2463  *val += 7;
2464  return 1;
2465  case 'x':
2466  *val += 8;
2467  return 1;
2468  case 'y':
2469  *val += 9;
2470  return 1;
2471  }
2472  return 0;
2473 }
2474 #endif
2475 
2476 static unsigned int
2477 cob_get_long_ebcdic_sign (const unsigned char *p, cob_s64_t *val)
2478 {
2479  switch (*p) {
2480  case '{':
2481  return 0;
2482  case 'A':
2483  *val += 1;
2484  return 0;
2485  case 'B':
2486  *val += 2;
2487  return 0;
2488  case 'C':
2489  *val += 3;
2490  return 0;
2491  case 'D':
2492  *val += 4;
2493  return 0;
2494  case 'E':
2495  *val += 5;
2496  return 0;
2497  case 'F':
2498  *val += 6;
2499  return 0;
2500  case 'G':
2501  *val += 7;
2502  return 0;
2503  case 'H':
2504  *val += 8;
2505  return 0;
2506  case 'I':
2507  *val += 9;
2508  return 0;
2509  case '}':
2510  return 1;
2511  case 'J':
2512  *val += 1;
2513  return 1;
2514  case 'K':
2515  *val += 2;
2516  return 1;
2517  case 'L':
2518  *val += 3;
2519  return 1;
2520  case 'M':
2521  *val += 4;
2522  return 1;
2523  case 'N':
2524  *val += 5;
2525  return 1;
2526  case 'O':
2527  *val += 6;
2528  return 1;
2529  case 'P':
2530  *val += 7;
2531  return 1;
2532  case 'Q':
2533  *val += 8;
2534  return 1;
2535  case 'R':
2536  *val += 9;
2537  return 1;
2538  }
2539  return 0;
2540 }
2541 
2542 int
2543 cob_cmp_numdisp (const unsigned char *data, const size_t size,
2544  const cob_s64_t n, const cob_u32_t has_sign)
2545 {
2546  const unsigned char *p;
2547  cob_s64_t val = 0;
2548  size_t inc;
2549 
2550  p = data;
2551  if (!has_sign) {
2552  if (unlikely(n < 0)) {
2553  return 1;
2554  }
2555  for (inc = 0; inc < size; inc++, p++) {
2556  val = (val * 10) + COB_D2I (*p);
2557  }
2558  return (val < n) ? -1 : (val > n);
2559  }
2560  for (inc = 0; inc < size - 1; inc++, p++) {
2561  val = (val * 10) + COB_D2I (*p);
2562  }
2563  val *= 10;
2564  if (*p >= (unsigned char)'0' && *p <= (unsigned char)'9') {
2565  val += COB_D2I (*p);
2566  } else {
2567  if (unlikely(COB_MODULE_PTR->ebcdic_sign)) {
2568  if (cob_get_long_ebcdic_sign (p, &val)) {
2569  val = -val;
2570  }
2571  } else {
2572 #ifdef COB_EBCDIC_MACHINE
2573  if (cob_get_long_ascii_sign (p, &val)) {
2574  val = -val;
2575  }
2576 #else
2577  if (*p >= (unsigned char)'p' && *p <= (unsigned char)'y') {
2578  val += (*p - (unsigned char)'p');
2579  val = -val;
2580  }
2581 #endif
2582  }
2583  }
2584  return (val < n) ? -1 : (val > n);
2585 }
2586 
2587 void
2589 {
2590  cob_decimal **dec;
2591  cob_u32_t i;
2592  va_list args;
2593 
2594  va_start (args, params);
2595  for (i = 0; i < params; ++i) {
2596  dec = va_arg (args, cob_decimal **);
2597  *dec = cob_decimal_base + i;
2598  }
2599  va_end (args);
2600 }
2601 
2602 void
2604 {
2605  cob_decimal **dec;
2606  cob_u32_t i;
2607  va_list args;
2608 
2609  va_start (args, params);
2610  for (i = 0; i < params; ++i) {
2611  dec = va_arg (args, cob_decimal **);
2612  *dec = cob_malloc (sizeof(cob_decimal));
2613  cob_decimal_init (*dec);
2614  }
2615  va_end (args);
2616 }
2617 
2618 void
2620 {
2621  cob_decimal *dec;
2622  cob_u32_t i;
2623  va_list args;
2624 
2625  va_start (args, params);
2626  for (i = 0; i < params; ++i) {
2627  dec = va_arg (args, cob_decimal *);
2628  mpz_clear (dec->value);
2629  cob_free (dec);
2630  }
2631  va_end (args);
2632 }
2633 
2634 /* Init/Exit routines */
2635 
2636 void
2638 {
2639  cob_decimal *d1;
2640  size_t i;
2641 
2642  if (cob_decimal_base) {
2643  d1 = cob_decimal_base;
2644  for (i = 0; i < COB_MAX_DEC_STRUCT; d1++, i++) {
2645  mpz_clear (d1->value);
2646  }
2647  cob_free (cob_decimal_base);
2648  }
2649 
2650  mpz_clear (cob_d_remainder.value);
2651 
2652  mpz_clear (cob_d3.value);
2653  mpz_clear (cob_d2.value);
2654  mpz_clear (cob_d1.value);
2655 
2656  mpz_clear (cob_mexp);
2657  mpz_clear (cob_mpzt2);
2658  mpz_clear (cob_mpzt);
2659 
2660  mpz_clear (cob_mpz_ten34m1);
2661  mpz_clear (cob_mpz_ten16m1);
2662  for (i = 0; i < COB_MAX_BINARY; i++) {
2663  mpz_clear (cob_mpze10[i]);
2664  }
2665 
2666  mpf_clear (cob_mpft_get);
2667  mpf_clear (cob_mpft);
2668 }
2669 
2670 void
2672 {
2673  cob_decimal *d1;
2674  cob_u32_t i;
2675 
2676  cobglobptr = lptr;
2677 
2678  memset (packed_value, 0, sizeof(packed_value));
2679  last_packed_val = 0;
2680 
2681  mpf_init2 (cob_mpft, COB_MPF_PREC);
2682  mpf_init2 (cob_mpft_get, COB_MPF_PREC);
2683 
2684  for (i = 0; i < COB_MAX_BINARY; i++) {
2685  mpz_init2 (cob_mpze10[i], 128UL);
2686  mpz_ui_pow_ui (cob_mpze10[i], 10UL, (cob_uli_t)i);
2687  }
2688  mpz_init_set (cob_mpz_ten16m1, cob_mpze10[16]);
2689  mpz_sub_ui (cob_mpz_ten16m1, cob_mpz_ten16m1, 1UL);
2690  mpz_init_set (cob_mpz_ten34m1, cob_mpze10[34]);
2691  mpz_sub_ui (cob_mpz_ten34m1, cob_mpz_ten34m1, 1UL);
2692 
2693  mpz_init2 (cob_mpzt, COB_MPZ_DEF);
2694  mpz_init2 (cob_mpzt2, COB_MPZ_DEF);
2695  mpz_init2 (cob_mexp, COB_MPZ_DEF);
2696 
2697  cob_decimal_init (&cob_d1);
2698  cob_decimal_init (&cob_d2);
2699  cob_decimal_init (&cob_d3);
2700  cob_decimal_init (&cob_d_remainder);
2701 
2702  cob_decimal_base = cob_malloc (COB_MAX_DEC_STRUCT * sizeof(cob_decimal));
2703  d1 = cob_decimal_base;
2704  for (i = 0; i < COB_MAX_DEC_STRUCT; d1++, i++) {
2705  cob_decimal_init (d1);
2706  }
2707 }
static mpz_t cob_mpz_ten16m1
Definition: numeric.c:119
static mpz_t cob_mpzt2
Definition: numeric.c:117
#define COB_DECIMAL_NAN
Definition: coblocal.h:80
void cob_free(void *mptr)
Definition: common.c:1284
static cob_decimal d2
Definition: intrinsic.c:80
#define COB_STORE_AWAY_FROM_ZERO
Definition: common.h:871
#define COB_128_EXPO_2
Definition: coblocal.h:137
void cob_set_packed_int(cob_field *f, const int val)
Definition: numeric.c:1261
void cob_sub(cob_field *f1, cob_field *f2, const int opt)
Definition: numeric.c:1940
static unsigned char packed_value[20]
Definition: numeric.c:125
static mpz_t cob_mpz_ten34m1
Definition: numeric.c:118
#define COB_FIELD_SCALE(f)
Definition: common.h:664
#define COB_128_EXPO_1
Definition: coblocal.h:133
int cob_sub_int(cob_field *f, const int n, const int opt)
Definition: numeric.c:2251
int cob_add_int(cob_field *f, const int n, const int opt)
Definition: numeric.c:2195
#define cob_u32_t
Definition: common.h:31
#define COB_FIELD_DATA(f)
Definition: common.h:668
#define COB_128_SIGF_2
Definition: coblocal.h:139
#define COB_STORE_NEAR_TOWARD_ZERO
Definition: common.h:874
static void cob_decimal_set_double(cob_decimal *d, const double v)
Definition: numeric.c:821
static void shift_decimal(cob_decimal *d, const int n)
Definition: numeric.c:394
static int cob_decimal_get_ieee128dec(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:612
static COB_INLINE COB_A_INLINE void cob_decimal_set(cob_decimal *dst, const cob_decimal *src)
Definition: numeric.c:356
static cob_global * cobglobptr
Definition: numeric.c:56
#define COB_FIELD_BINARY_SWAP(f)
Definition: common.h:648
void cob_mul(cob_field *f1, cob_field *f2, const int opt)
Definition: numeric.c:1949
#define COB_TYPE_NUMERIC_PACKED
Definition: common.h:609
#define COB_STORE_NEAR_AWAY_FROM_ZERO
Definition: common.h:872
static mpz_t cob_mexp
Definition: numeric.c:115
static void cob_decimal_do_round(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:1693
void cob_set_packed_zero(cob_field *f)
Definition: numeric.c:1073
void cob_move(cob_field *, cob_field *)
Definition: move.c:1170
int cob_cmp_float(cob_field *f1, cob_field *f2)
Definition: numeric.c:2315
#define COB_64_OR_EXTEND
Definition: coblocal.h:130
static mpf_t cob_mpft_get
Definition: numeric.c:123
void cob_decimal_mul(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:1891
#define COB_FIELD_TYPE(f)
Definition: common.h:662
#define COB_64_EXPO_2
Definition: coblocal.h:126
static unsigned int cob_get_long_ebcdic_sign(const unsigned char *p, cob_s64_t *val)
Definition: numeric.c:2477
void cob_div_quotient(cob_field *dividend, cob_field *divisor, cob_field *quotient, const int opt)
Definition: numeric.c:1967
static int cob_packed_get_sign(const cob_field *f)
Definition: numeric.c:910
#define CB_FMT_PLLD
Definition: common.h:58
#define COB_STORE_ROUND
Definition: common.h:867
#define COB_STORE_NEAR_EVEN
Definition: common.h:873
static double cob_decimal_get_double(cob_decimal *d)
Definition: numeric.c:877
static COB_INLINE COB_A_INLINE void num_byte_memcpy(unsigned char *s1, const unsigned char *s2, size_t size)
Definition: numeric.c:229
cob_field f2
Definition: cobxref.c.l.h:55
#define COB_FIELD_IS_FP(f)
Definition: common.h:652
static cob_u64_t last_packed_val
Definition: numeric.c:126
void cob_decimal_setget_fld(cob_field *src, cob_field *dst, const int opt)
Definition: numeric.c:2007
#define COB_128_OR_EXTEND
Definition: coblocal.h:141
#define COB_INLINE
Definition: common.h:354
void cob_decimal_set_field(cob_decimal *d, cob_field *f)
Definition: numeric.c:1612
static mpz_t cob_mpze10[COB_MAX_BINARY]
Definition: numeric.c:120
cob_decimal * d1
Definition: cobxref.c.l.h:21
#define COB_MAX_DEC_STRUCT
Definition: common.h:571
#define COB_ATTR_INIT(u, v, x, y, z)
Definition: coblocal.h:150
static cob_decimal cob_d_remainder
Definition: numeric.c:111
unsigned char * data
Definition: common.h:952
void cob_decimal_sub(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:1883
#define COB_MPZ_DEF
Definition: coblocal.h:86
#define COB_128_SIGF_1
Definition: coblocal.h:135
static cob_decimal cob_d3
Definition: numeric.c:110
#define cob_s64_t
Definition: common.h:51
#define COB_STORE_MASK
Definition: common.h:880
void cob_decimal_pop(const cob_u32_t params,...)
Definition: numeric.c:2619
static void cob_decimal_set_ieee64dec(cob_decimal *d, const cob_field *f)
Definition: numeric.c:551
#define COB_FLAG_HAVE_SIGN
Definition: common.h:630
void cob_gmp_free(void *ptr)
Definition: numeric.c:217
#define TOLERANCE
Definition: numeric.c:2310
#define COB_MAX_DIGITS
Definition: common.h:562
#define COB_I2D(x)
Definition: coblocal.h:183
int cob_decimal_cmp(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:1922
#define COB_64_EXPO_1
Definition: coblocal.h:122
#define cob_uli_t
Definition: common.h:33
static COB_INLINE COB_A_INLINE void cob_binary_set_uint64(cob_field *f, cob_u64_t n)
Definition: numeric.c:283
#define COB_TYPE_NUMERIC_FP_DEC64
Definition: common.h:613
#define COB_FIELD_NO_SIGN_NIBBLE(f)
Definition: common.h:651
int cob_cmp_packed(cob_field *f, const cob_s64_t val)
Definition: numeric.c:2362
#define COB_GET_SIGN(f)
Definition: coblocal.h:158
void cob_exit_numeric(void)
Definition: numeric.c:2637
#define COB_TYPE_NUMERIC_FLOAT
Definition: common.h:610
#define unlikely(x)
Definition: common.h:437
static int cob_decimal_get_ieee64dec(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:481
#define FLOAT_EQ(x, y, t)
Definition: numeric.c:2312
void cob_decimal_add(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:1875
int cob_cmp_int(cob_field *f1, const int n)
Definition: numeric.c:2257
int cob_numeric_cmp(cob_field *f1, cob_field *f2)
Definition: numeric.c:2348
static mpz_t cob_mpzt
Definition: numeric.c:116
EC ARGUMENT EC EC BOUND EC BOUND EC BOUND EC BOUND TABLE EC DATA EC DATA EC DATA PTR NULL
Definition: exception.def:95
if sign
Definition: flag.def:42
int cob_cmp_numdisp(const unsigned char *data, const size_t size, const cob_s64_t n, const cob_u32_t has_sign)
Definition: numeric.c:2543
#define COB_64_SIGF_2
Definition: coblocal.h:128
static void cob_decimal_set_binary(cob_decimal *d, cob_field *f)
Definition: numeric.c:1424
static int cob_decimal_get_packed(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:1147
#define COB_STORE_TRUNCATION
Definition: common.h:878
cob_field f1
Definition: cobxref.c.l.h:54
#define COB_FIELD_BINARY_TRUNC(f)
Definition: common.h:654
#define COB_TYPE_NUMERIC_BINARY
Definition: common.h:608
void cob_set_exception(const int id)
Definition: common.c:1212
#define COB_128_LSW(x)
Definition: coblocal.h:103
#define COB_64_SIGF_1
Definition: coblocal.h:124
void cob_decimal_alloc(const cob_u32_t params,...)
Definition: numeric.c:2588
#define COB_STORE_KEEP_ON_OVERFLOW
Definition: common.h:868
#define COB_TYPE_NUMERIC_DISPLAY
Definition: common.h:607
#define cob_sli_t
Definition: common.h:32
#define COB_TYPE_NUMERIC_FP_BIN128
Definition: common.h:617
#define COB_PUT_SIGN(f, s)
Definition: coblocal.h:160
#define COB_MODULE_PTR
Definition: coblocal.h:185
static int cob_decimal_get_binary(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:1507
void cob_div(cob_field *f1, cob_field *f2, const int opt)
Definition: numeric.c:1958
static void cob_decimal_set_display(cob_decimal *d, cob_field *f)
Definition: numeric.c:1308
#define COB_U64_C(x)
Definition: common.h:55
void cob_init_numeric(cob_global *lptr)
Definition: numeric.c:2671
static COB_INLINE COB_A_INLINE void cob_binary_set_int64(cob_field *f, cob_s64_t n)
Definition: numeric.c:301
#define COB_DEC_SIGN
Definition: coblocal.h:112
int cob_cmp_llint(cob_field *f1, const cob_s64_t n)
Definition: numeric.c:2275
#define COB_STORE_PROHIBITED
Definition: common.h:875
static mpf_t cob_mpft
Definition: numeric.c:122
#define COB_64_IS_SPECIAL(x)
Definition: coblocal.h:114
#define COB_A_INLINE
Definition: common.h:440
size_t size
Definition: common.h:951
#define COB_TYPE_NUMERIC_DOUBLE
Definition: common.h:611
#define COB_64_IS_EXTEND(x)
Definition: coblocal.h:117
#define COB_STORE_TOWARD_GREATER
Definition: common.h:876
strict implicit external call column overflow
Definition: warning.def:63
void cob_add(cob_field *f1, cob_field *f2, const int opt)
Definition: numeric.c:1931
void cob_decimal_div(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:1899
#define COB_DEC_EXTEND
Definition: coblocal.h:110
const cob_field_attr * attr
Definition: common.h:953
#define COB_MPF_PREC
Definition: coblocal.h:89
static void cob_decimal_set_packed(cob_decimal *d, cob_field *f)
Definition: numeric.c:1087
#define CB_FMT_PLLU
Definition: common.h:59
void * cob_malloc(const size_t size)
Definition: common.c:1250
#define DECIMAL_CHECK(d1, d2)
Definition: numeric.c:47
static cob_decimal cob_d2
Definition: numeric.c:109
#define COB_STORE_TOWARD_LESSER
Definition: common.h:877
#define COB_128_MSW(x)
Definition: coblocal.h:102
#define COB_STORE_TRUNC_ON_OVERFLOW
Definition: common.h:869
#define COB_FIELD_HAVE_SIGN(f)
Definition: common.h:643
static void align_decimal(cob_decimal *d1, cob_decimal *d2)
Definition: numeric.c:411
static void cob_decimal_print(cob_decimal *d, FILE *fp)
Definition: numeric.c:364
void * cob_fast_malloc(const size_t size)
Definition: common.c:1296
int cob_exception_code
Definition: common.h:1203
int cob_cmp_uint(cob_field *f1, const unsigned int n)
Definition: numeric.c:2266
void cob_decimal_init(cob_decimal *d)
Definition: numeric.c:321
static const unsigned char packed_bytes[]
Definition: numeric.c:58
#define COB_D2I(x)
Definition: coblocal.h:177
mpz_t value
Definition: common.h:985
static cob_decimal * cob_decimal_base
Definition: numeric.c:113
#define COB_TYPE_NUMERIC_FP_DEC128
Definition: common.h:614
int cob_decimal_get_field(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:1801
#define cob_u64_t
Definition: common.h:52
#define COB_MAX_BINARY
Definition: common.h:565
#define COB_UNUSED(z)
Definition: common.h:535
#define COB_DECIMAL_INF
Definition: coblocal.h:83
void cob_decimal_push(const cob_u32_t params,...)
Definition: numeric.c:2603
void cob_print_realbin(const cob_field *f, FILE *fp, const int size)
Definition: numeric.c:1676
void cob_decimal_set_llint(cob_decimal *d, const cob_s64_t n)
Definition: numeric.c:328
#define COB_FIELD_DIGITS(f)
Definition: common.h:663
#define COB_MPZ_ENDIAN
Definition: coblocal.h:104
#define COB_128_IS_SPECIAL(x)
Definition: coblocal.h:115
strict implicit external call params
Definition: warning.def:60
static cob_decimal cob_d1
Definition: numeric.c:108
static COB_INLINE COB_A_INLINE cob_u64_t cob_binary_get_uint64(const cob_field *const f)
Definition: numeric.c:263
#define COB_BSWAP_64(val)
Definition: common.h:258
void cob_print_ieeedec(const cob_field *f, FILE *fp)
Definition: numeric.c:1647
static COB_INLINE COB_A_INLINE cob_s64_t cob_binary_get_sint64(const cob_field *const f)
Definition: numeric.c:237
#define COB_FIELD_SIZE(f)
Definition: common.h:671
#define COB_128_IS_EXTEND(x)
Definition: coblocal.h:118
static int cob_decimal_get_display(cob_decimal *d, cob_field *f, const int opt)
Definition: numeric.c:1371
static void cob_decimal_set_ieee128dec(cob_decimal *d, const cob_field *f)
Definition: numeric.c:688
int scale
Definition: common.h:986
void cob_div_remainder(cob_field *fld_remainder, const int opt)
Definition: numeric.c:2001