GnuCOBOL  2.0
A free COBOL compiler
isdecimal.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Trevor van Bremen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1,
7  * or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; see the file COPYING.LIB. If
16  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
17  * Boston, MA 02110-1301 USA
18  */
19 
20 #include "isinternal.h"
21 
22 #define ACCSIZE (DECSIZE + 1)
23 
24 struct decacc {
25  short dec_exp;
26  short dec_pos;
27  short dec_ndgts;
29 };
30 
31 /* Local functions */
32 
33 static void
34 comp100 (unsigned char *cp, int count)
35 {
36  int base;
37 
38  base = 100;
39  cp += count;
40  while (count--) {
41  cp--;
42  *cp = base - *cp;
43  if (*cp > 99) {
44  *cp -= 100;
45  base = 100;
46  } else {
47  base = 99;
48  }
49  }
50 }
51 
52 static int
53 round100 (unsigned char *cp, int len)
54 {
55  int carry = 1;
56  int count = len;
57 
58  cp += len;
59  while (len-- > 0) {
60  cp--;
61  *cp = *cp + carry;
62  if (*cp > 99) {
63  *cp -= 100;
64  carry = 1;
65  } else {
66  carry = 0;
67  }
68  }
69 
70  if (carry) {
71  for (len = count; --len;) {
72  cp[len - 1] = cp[len];
73  }
74  cp[0] = 1;
75  return 1;
76  }
77  return 0;
78 }
79 
80 static int
81 deccvfix (long i, dec_t *dp)
82 {
83  int j;
84  char buffer[DECSIZE];
85 
86  if (i < 0) {
87  dp->dec_pos = 0;
88  i = -i;
89  } else {
90  dp->dec_pos = 1;
91  }
92 
93  dp->dec_exp = 0;
94  j = 0;
95 
96  while (i != 0) {
97  if ((buffer[j] = i % 100) || (j != 0)) {
98  j++;
99  }
100  dp->dec_exp++;
101  i /= 100;
102  }
103  dp->dec_ndgts = j;
104 
105  while (j != 0) {
106  dp->dec_dgts[i++] = buffer[--j];
107  }
108 
109  return 0;
110 }
111 
112 static void
113 dectofix (dec_t *dp, long *ip)
114 {
115  long i = 0;
116  unsigned char *digits = dp->dec_dgts;
117  int expon = dp->dec_exp;
118  int valid = dp->dec_ndgts;
119 
120  while (expon-- > 0) {
121  i = i * 100;
122  if (valid-- > 0) {
123  i += *digits++;
124  }
125  }
126  *ip = (dp->dec_pos) ? i : -i;
127 }
128 
129 static int
130 deccvreal (double dbl, dec_t *dp, int ndigits)
131 {
132  unsigned char *str;
133  unsigned char *dgt;
134  int decpt;
135  int sign;
136 
137  str = (unsigned char *)ecvt (dbl, ndigits, &decpt, &sign);
138 
139  dp->dec_pos = sign ? 0 : 1;
140  dp->dec_exp = (decpt + (decpt > 0 ? 1 : 0)) / 2;
141 
142  dgt = dp->dec_dgts;
143 
144  if (decpt & 1) {
145  *dgt++ = *str++ - '0';
146  ndigits--;
147  }
148 
149  while (ndigits-- > 0) {
150  *dgt++ = (*str++ - '0') * 10;
151  if (ndigits-- > 0) {
152  dgt[-1] += *str++ - '0';
153  }
154  }
155 
156  while (--dgt >= dp->dec_dgts && *dgt == 0) ;
157 
158  dp->dec_ndgts = 1 + dgt - dp->dec_dgts;
159 
160  return 0;
161 }
162 
163 static int
164 dectoreal (dec_t *dp, double *dblp, int valid)
165 {
166  unsigned char *digits = dp->dec_dgts;
167  double dbl;
168 
169  if (valid > dp->dec_ndgts) {
170  valid = dp->dec_ndgts;
171  }
172 
173  dbl = 0.0;
174 
175  while (valid-- > 0) {
176  dbl = (dbl + digits[valid]) / 100.0;
177  }
178 
179  if (dp->dec_pos == 0) {
180  dbl = -dbl;
181  }
182 
183  if (dp->dec_exp > 0) {
184  int i = dp->dec_exp;
185 
186  while (i--) {
187  dbl *= 100.0;
188  }
189  } else if (dp->dec_exp < 0) {
190  int i = dp->dec_exp;
191 
192  while (i++) {
193  dbl /= 100.0;
194  }
195  }
196 
197  *dblp = dbl;
198 
199  return 0;
200 }
201 
202 static char *
203 decefcvt (dec_t *np, int dg, int *pt, int *sg, int fl)
204 {
205  static char *ds = NULL;
206  int i, j, k, nd;
207  dec_t rd;
208 
209  if (!ds) {
210  ds = calloc (1, 160);
211  }
212  ds[0] = 0;
213  if (np->dec_pos == -1) {
214  return ds;
215  }
216  *sg = np->dec_pos ^ 1;
217  *pt = np->dec_exp * 2;
218  nd = np->dec_ndgts;
219  if (nd && np->dec_dgts[0] < 10) {
220  *pt -= 1;
221  }
222  k = dg;
223  if (fl) {
224  k += *pt;
225  }
226  if (k < 0) {
227  return ds;
228  }
229  i = 0;
230  if (nd && np->dec_dgts[0] < 10) {
231  i = 1;
232  }
233  rd.dec_pos = np->dec_pos;
234  rd.dec_ndgts = 1;
235  rd.dec_exp = np->dec_exp - (k + i) / 2;
236  if ((k + i) & 1) {
237  rd.dec_dgts[0] = 5;
238  } else {
239  rd.dec_dgts[0] = 50;
240  }
241  if (nd == 0) {
242  rd.dec_ndgts = 0;
243  rd.dec_dgts[0] = 0;
244  }
245  if (decadd (np, &rd, &rd)) {
246  return ds;
247  }
248  i = 0;
249  *pt = rd.dec_exp * 2;
250  if (nd && rd.dec_dgts[0] < 10) {
251  *pt -= 1;
252  i = 1;
253  }
254  if (fl) {
255  dg += *pt;
256  }
257  j = 0;
258  while (j < dg && j < 151) {
259  if (i / 2 < rd.dec_ndgts) {
260  k = rd.dec_dgts[i / 2];
261  } else {
262  k = 0;
263  }
264  if (i & 1) {
265  k %= 10;
266  } else {
267  k /= 10;
268  }
269  ds[j] = k + '0';
270  i += 1;
271  j += 1;
272  }
273  ds[j] = 0;
274  return ds;
275 }
276 
277 static int
278 dec_round (struct decacc *s, int c)
279 {
280  int i, j;
281 
282  if (c > 0) {
283  i = ACCSIZE;
284  while (--i) {
285  s->dec_dgts[i] = s->dec_dgts[i - 1];
286  }
287  s->dec_dgts[0] = c;
288  s->dec_exp += 1;
289  s->dec_ndgts += 1;
290  } else {
291  i = 0;
292  j = 0;
293  while (s->dec_dgts[j] == 0 && j < s->dec_ndgts) {
294  j += 1;
295  }
296  if (j == s->dec_ndgts) {
297  s->dec_exp = 0;
298  s->dec_pos = 1;
299  } else if (j) {
300  s->dec_exp -= j;
301  while (j < s->dec_ndgts) {
302  s->dec_dgts[i++] = s->dec_dgts[j++];
303  }
304  while (i < s->dec_ndgts) {
305  s->dec_dgts[i++] = 0;
306  }
307  }
308  }
309  i = DECSIZE;
310  if (s->dec_pos) {
311  j = 1;
312  } else {
313  j = -1;
314  }
315  if (s->dec_dgts[DECSIZE] > 49) {
316  while (i--) {
317  j += s->dec_dgts[i];
318  if (j > 99) {
319  s->dec_dgts[i] = j - 100;
320  j = 1;
321  } else if (j < 0) {
322  s->dec_dgts[i] = j + 100;
323  j = -1;
324  } else {
325  s->dec_dgts[i] = j;
326  break;
327  }
328  }
329  }
330  i = s->dec_ndgts;
331  if (i > DECSIZE) {
332  i = DECSIZE;
333  }
334  while (i--) {
335  if (s->dec_dgts[i]) {
336  break;
337  }
338  }
339  s->dec_ndgts = i + 1;
340  if (s->dec_exp > 0x3f) {
341  s->dec_exp = 0x3f;
342  return -1200;
343  }
344  if (s->dec_exp < -0x40) {
345  s->dec_exp = -0x40;
346  return -1201;
347  }
348  return 0;
349 }
350 
351 /* Global functions */
352 
353 void
354 deccopy (dec_t *src, dec_t *dst)
355 {
356  memcpy (dst, src, sizeof (dec_t));
357 }
358 
359 int
360 deccvint (int i, dec_t *dp)
361 {
362  if ((unsigned)i == (unsigned)VAL_DECPOSNULL (int)) {
363  dp->dec_pos = -1;
364  dp->dec_exp = 0;
365  dp->dec_ndgts = 0;
366  return 0;
367  }
368  return deccvfix ((long)i, dp);
369 }
370 
371 int
372 dectoint (dec_t *dp, int *ip)
373 {
374  long lp;
375 
376  if (dp->dec_pos == DECPOSNULL) {
377  *ip = VAL_DECPOSNULL (int);
378  } else {
379  dectofix (dp, &lp);
380  *ip = lp;
381  }
382  return 0;
383 }
384 
385 int
386 deccvlong (long i, dec_t *dp)
387 {
388  if (i == VAL_DECPOSNULL (long)) {
389  dp->dec_pos = -1;
390  dp->dec_exp = 0;
391  dp->dec_ndgts = 0;
392  return 0;
393  }
394 
395  return deccvfix ((long)i, dp);
396 }
397 
398 int
399 dectolong (dec_t *dp, long *ip)
400 {
401  if (dp->dec_pos == DECPOSNULL) {
402  *ip = VAL_DECPOSNULL (long);
403  } else {
404  dectofix (dp, ip);
405  }
406  return 0;
407 }
408 
409 int
410 deccvdbl (double dbl, dec_t *dp)
411 {
412  return deccvreal (dbl, dp, 16);
413 }
414 
415 int
416 dectodbl (dec_t *dp, double *dblp)
417 {
418  return dectoreal (dp, dblp, 16);
419 }
420 
421 int
422 deccvflt (float flt, dec_t *dp)
423 {
424  return deccvreal (flt, dp, 8);
425 }
426 
427 int
428 dectoflt (dec_t *dp, float *fltp)
429 {
430  double dbl;
431  int status;
432 
433  status = dectoreal (dp, &dbl, 8);
434  *fltp = dbl;
435  return status;
436 }
437 
438 void
439 stdecimal (dec_t *dp, unsigned char *cp, int len)
440 {
441  unsigned char *bp;
442  unsigned char buffer[DECSIZE];
443  unsigned char header;
444  int count;
445 
446  if (dp->dec_pos == -1) {
447  memset (cp, 0, len);
448  return;
449  }
450 
451  header = 0xC0 + dp->dec_exp;
452  len--;
453 
454  if ((count = dp->dec_ndgts)) {
455  memcpy (buffer, dp->dec_dgts, count);
456 
457  if (len < count && buffer[len] >= 50) {
458  header += round100 (buffer, len);
459  }
460 
461  if (dp->dec_pos == 0) {
462  header = ~header;
463  comp100 (buffer, len < count ? len : count);
464  }
465  }
466 
467  *cp = header;
468 
469  bp = buffer;
470  while (len-- > 0) {
471  *++cp = (count-- > 0) ? *bp++ : 0;
472  }
473 
474  return;
475 }
476 
477 int
478 lddecimal (unsigned char *cp, int len, dec_t *dp)
479 {
480  unsigned char buffer[DECSIZE + 1];
481  unsigned char *digits;
482 
483  if (*cp == 0) {
484  dp->dec_pos = -1;
485  dp->dec_exp = 0;
486  dp->dec_ndgts = 0;
487  return 0;
488  }
489 
490  if (--len > DECSIZE) {
491  len = DECSIZE;
492  }
493 
494  memcpy (buffer, cp + 1, len);
495 
496  if (*cp & 0x80) {
497  dp->dec_pos = 1;
498  dp->dec_exp = *cp - 0xC0;
499  } else {
500  comp100 (buffer, len);
501  dp->dec_pos = 0;
502  dp->dec_exp = 0xFF - (*cp) - 0xC0;
503  }
504 
505  cp = buffer + len;
506 
507  while (len > 0 && *--cp == 0) {
508  len--;
509  }
510  dp->dec_ndgts = len;
511 
512  digits = dp->dec_dgts;
513  cp = buffer;
514  while (len-- > 0) {
515  *digits++ = *cp++;
516  }
517 
518  return 0;
519 }
520 
521 int
522 decsub (dec_t *x, dec_t *y, dec_t *r)
523 {
524  int i;
525 
526  if (x->dec_pos == -1 || y->dec_pos == -1) {
527  r->dec_pos = -1;
528  r->dec_ndgts = 0;
529  r->dec_exp = 0;
530  return 0;
531  }
532  y->dec_pos ^= 1;
533  i = decadd (x, y, r);
534  if (y != r) {
535  y->dec_pos ^= 1;
536  }
537  return i;
538 }
539 
540 int
541 decadd (dec_t *x, dec_t *y, dec_t *r)
542 {
543  int a, c, i, j;
544  struct decacc *z, zv;
545  dec_t *t;
546 
547  if (x->dec_pos == -1 || y->dec_pos == -1) {
548  r->dec_pos = -1;
549  r->dec_ndgts = 0;
550  r->dec_exp = 0;
551  return 0;
552  }
553  z = &zv;
554  memset (z, 0, sizeof (struct decacc));
555  i = x->dec_pos;
556  j = y->dec_pos;
557  x->dec_pos = 1;
558  y->dec_pos = 1;
559  if (deccmp (x, y) < 0) {
560  t = x;
561  x = y;
562  y = t;
563  c = i;
564  i = j;
565  j = c;
566  }
567  x->dec_pos = i;
568  y->dec_pos = j;
569 
570  memcpy (z, x, sizeof (dec_t));
571  a = x->dec_exp - y->dec_exp;
572 
573  if (a > DECSIZE) {
574  memcpy (r, x, sizeof (dec_t));
575  return 0;
576  }
577  i = y->dec_ndgts + a;
578  if (i > ACCSIZE) {
579  i = ACCSIZE;
580  }
581  if (i > z->dec_ndgts) {
582  z->dec_ndgts = i;
583  }
584  if ((j = i - a) < 0) {
585  j = 0;
586  }
587  c = 0;
588  while (i--) {
589  if (j) {
590  j -= 1;
591  if (x->dec_pos == y->dec_pos) {
592  c += y->dec_dgts[j];
593  } else {
594  c -= y->dec_dgts[j];
595  }
596  }
597  c += z->dec_dgts[i];
598  if (c < 0) {
599  z->dec_dgts[i] = c + 100;
600  c = -1;
601  } else if (c < 100) {
602  z->dec_dgts[i] = c;
603  c = 0;
604  } else {
605  z->dec_dgts[i] = c - 100;
606  c = 1;
607  }
608  }
609  i = dec_round (z, c);
610  memcpy (r, z, sizeof (dec_t));
611  return i;
612 }
613 
614 int
615 decmul (dec_t *x, dec_t *y, dec_t *r)
616 {
617  struct decacc *p, pv;
618  int i, j, k = 0;
619 
620  if (x->dec_pos == -1 || y->dec_pos == -1) {
621  r->dec_pos = -1;
622  r->dec_ndgts = 0;
623  r->dec_exp = 0;
624  return 0;
625  }
626  p = &pv;
627  memset (p, 0, sizeof (struct decacc));
628  for (i = x->dec_ndgts; i >= 0; i--) {
629  k = 0;
630  for (j = y->dec_ndgts - 1; j >= 0; j--) {
631  if (i + j < ACCSIZE) {
632  k += p->dec_dgts[i + j] + x->dec_dgts[i] * y->dec_dgts[j];
633  p->dec_dgts[i + j] = k % 100;
634  k /= 100;
635  }
636  if (i) {
637  p->dec_dgts[i - 1] = k;
638  }
639  }
640  }
641  p->dec_pos = x->dec_pos ^ y->dec_pos ^ 1;
642  p->dec_exp = x->dec_exp + y->dec_exp - 1;
643  p->dec_ndgts = x->dec_ndgts + y->dec_ndgts;
644  if (k) {
645  k = dec_round (p, k);
646  } else {
647  p->dec_ndgts -= 1;
648  }
649  memcpy (r, p, sizeof (dec_t));
650  return k;
651 }
652 
653 int
654 decdiv (dec_t *x, dec_t *y, dec_t *r)
655 {
656  int j, c, n, i, m, s, t, u = 0;
657  struct decacc *q, qv, *a, av;
658 
659  if (x->dec_pos == -1 || y->dec_pos == -1) {
660  r->dec_pos = -1;
661  r->dec_ndgts = 0;
662  r->dec_exp = 0;
663  return 0;
664  }
665 
666  if (y->dec_ndgts == 0) {
667  r->dec_pos = 1;
668  r->dec_ndgts = 0;
669  r->dec_exp = 0;
670  return -1202;
671  }
672 
673  q = &qv;
674  a = &av;
675  memset (q, 0, sizeof (struct decacc));
676  q->dec_exp = x->dec_exp - y->dec_exp + 1;
677  q->dec_pos = x->dec_pos ^ y->dec_pos ^ 1;
678  q->dec_ndgts = ACCSIZE;
679  memcpy (a, x, sizeof (dec_t));
680  a->dec_exp = a->dec_pos = a->dec_dgts[ACCSIZE - 1] = 0;
681 
682  m = -1;
683  for (n = 0; n < ACCSIZE; n += 1) {
684  if (n == 0 || a->dec_dgts[n - 1] == 0) {
685  i = n;
686  } else {
687  i = n - 1;
688  }
689  if (n != 1 || u != 0) {
690  m += 1;
691  } else {
692  q->dec_exp -= 1;
693  }
694  t = a->dec_dgts[i] * 100;
695  if (i < ACCSIZE - 1) {
696  t += a->dec_dgts[i + 1];
697  }
698  t += 1;
699  s = y->dec_dgts[0] * 100;
700  if (y->dec_ndgts > 1) {
701  s += y->dec_dgts[1];
702  }
703  if (i == n) {
704  u = t / s;
705  } else {
706  u = ((long)t) * 100 / s;
707  }
708  c = 0;
709  if (u) {
710  if (u > 99) {
711  u = 99;
712  }
713  j = y->dec_ndgts;
714  if (i + j > ACCSIZE) {
715  j = ACCSIZE - i;
716  c = -(y->dec_dgts[j] * u / 100);
717  }
718  while (j + n > i) {
719  j -= 1;
720  c += a->dec_dgts[n + j];
721  if (j >= 0) {
722  c -= y->dec_dgts[j] * u;
723  }
724  if (c < 0) {
725  a->dec_dgts[n + j] = (c + 10000) % 100;
726  c = (c + 1) / 100 - 1;
727  } else if (c > 99) {
728  a->dec_dgts[n + j] = c % 100;
729  c /= 100;
730  } else {
731  a->dec_dgts[n + j] = c;
732  c = 0;
733  }
734  }
735  if (c < 0) {
736  c = 0;
737  j = y->dec_ndgts;
738  if (i + j > ACCSIZE) {
739  j = ACCSIZE - i;
740  }
741  u -= 1;
742  while (j + n > i) {
743  j -= 1;
744  c += a->dec_dgts[n + j];
745  if (j >= 0) {
746  c += y->dec_dgts[j];
747  }
748  if (c > 99) {
749  a->dec_dgts[n + j] = c - 100;
750  c = 1;
751  } else {
752  a->dec_dgts[n + j] = c;
753  c = 0;
754  }
755  }
756  }
757  }
758  q->dec_dgts[m] = u;
759  }
760  if (s > 99) {
761  s = s / 100;
762  }
763  q->dec_dgts[DECSIZE] = a->dec_dgts[DECSIZE] * 100 / s;
764  i = dec_round (q, 0);
765  memcpy (r, q, sizeof (dec_t));
766  return i;
767 }
768 
769 int
770 deccmp (dec_t *x, dec_t *y)
771 {
772  int i, s;
773 
774  if (x->dec_pos == -1 || y->dec_pos == -1) {
775  return -2;
776  }
777  s = x->dec_pos - y->dec_pos;
778  if (s == 0) {
779  s = x->dec_exp - y->dec_exp;
780  if (s == 0) {
781  for (i = 0; i < DECSIZE; i += 1) {
782  if (i < x->dec_ndgts) {
783  s += x->dec_dgts[i];
784  }
785  if (i < y->dec_ndgts) {
786  s -= y->dec_dgts[i];
787  }
788  if (s) {
789  break;
790  }
791  }
792  }
793  }
794  if (s > 0) {
795  return 1;
796  }
797  if (s < 0) {
798  return -1;
799  }
800  return 0;
801 }
802 
803 int
804 dectoasc (dec_t *np, char *cp, int ln, int dg)
805 {
806  int i, j, m, t, pt, sg;
807  char *v;
808 
809  memset (cp, ' ', ln);
810  if (np->dec_pos == DECPOSNULL) {
811  return 0;
812  }
813  if (dg <= 0) {
814  i = np->dec_ndgts;
815  dg = i + i;
816  if (dg > 0 && np->dec_dgts[0] < 10) {
817  dg--;
818  }
819  if ((dg > 1 && np->dec_dgts[i - 1] % 10) == 0) {
820  dg--;
821  }
822  if (dg <= 0) {
823  dg = 1;
824  }
825  i = np->dec_pos ^ 1;
826  if (dg > ln - i - 1) {
827  dg = ln - i - 1;
828  }
829  v = dececvt (np, dg, &pt, &sg);
830  if (pt < 0 && dg + sg - pt + 1 >= ln) {
831  goto cv_float;
832  }
833  if (pt < 0) {
834  dg -= pt;
835  }
836  }
837  v = decfcvt (np, dg, &pt, &sg);
838  i = strlen (v);
839  if (pt != i) {
840  i++;
841  }
842  i += sg;
843  if (i > ln) {
844  i -= ln;
845  if (i <= dg) {
846  v = decfcvt (np, dg - i, &pt, &sg);
847  }
848  }
849  i = j = 0;
850  if (i < ln && sg) {
851  cp[i++] = '-';
852  }
853  if (i < ln && pt <= 0) {
854  cp[i++] = '0';
855  }
856  m = pt;
857  while (m > 0 && v[j] != '\0' && i < ln) {
858  cp[i++] = v[j++];
859  m--;
860  }
861  if (i < ln) {
862  cp[i++] = '.';
863  }
864  while (m < 0 && i < ln) {
865  cp[i++] = '0';
866  m++;
867  }
868  while (v[j] != '\0' && i < ln) {
869  cp[i++] = v[j++];
870  }
871  if (pt <= ln - sg) {
872  return 0;
873  }
874 
875  cv_float:
876  while (ln) {
877  memset (cp, ' ', ln);
878  m = ln;
879  i = 0;
880  i = pt - 1;
881  if (i < 0) {
882  i = -i;
883  }
884  do {
885  if (m > 0) {
886  cp[--m] = i % 10 + '0';
887  }
888  i /= 10;
889  } while (m && i);
890  if (m && pt <= 0) {
891  cp[--m] = '-';
892  }
893  if (m) {
894  cp[--m] = 'e';
895  }
896  dg = m - 1;
897  i = 0;
898  if (sg && m) {
899  dg -= 1;
900  cp[i++] = '-';
901  }
902  if (i >= m) {
903  if (np->dec_exp < -1) {
904  memset (cp, ' ', ln);
905  cp[0] = '0';
906  } else {
907  memset (cp, '*', ln);
908  }
909  return 0;
910  }
911  if (dg <= 0) {
912  dg = 1;
913  }
914  t = pt;
915  v = dececvt (np, dg, &pt, &sg);
916  if (t != pt) {
917  continue;
918  }
919  j = 0;
920  cp[i++] = v[j++];
921  if (i < m) {
922  cp[i++] = '.';
923  }
924  while (i < m) {
925  cp[i++] = v[j++];
926  }
927  while (m && (cp[--m] == '0' || cp[m] == '\0')) {
928  for (i = m; i < ln - 1; i++) {
929  cp[i] = cp[i + 1];
930  }
931  cp[i] = ' ';
932  }
933  if (m && cp[m] == '.') {
934  for (i = m; i < ln - 1; i++) {
935  cp[i] = cp[i + 1];
936  }
937  cp[i] = ' ';
938  }
939  ln = 0;
940  }
941  return 0;
942 }
943 
944 int
945 deccvasc (char *cp, int ln, dec_t *rp)
946 {
947  int c;
948  int ps, i, j, xs, xv, ms;
949  struct decacc *np, nv;
950 
951  np = &nv;
952  memset (np, 0, sizeof nv);
953  ps = i = j = xs = xv = ms = 0;
954  rp->dec_pos = np->dec_pos = DECPOSNULL;
955  np->dec_pos = 1;
956  while (i < ln && cp[i] == ' ') {
957  i += 1;
958  }
959  if (i == ln) {
960  return 0;
961  }
962  if (cp[i] == '-') {
963  i += 1;
964  ms = 0;
965  } else {
966  if (cp[i] == '+') {
967  i++;
968  }
969  ms = 1;
970  }
971  while (i < ln) {
972  c = cp[i++];
973  if (c >= '0' && c <= '9') {
974  if (ps) {
975  ps--;
976  }
977  c = c - '0';
978  if ((j || c) && j < ACCSIZE * 2) {
979  if (j & 1) {
980  np->dec_dgts[j / 2] += c;
981  } else {
982  np->dec_dgts[j / 2] = c * 10;
983  }
984  j += 1;
985  }
986  } else if (c == '.') {
987  if (ps) {
988  return -1213;
989  } else {
990  ps -= 1;
991  }
992  } else {
993  break;
994  }
995  }
996  if (i < ln && (c == 'e' || c == 'E')) {
997  c = cp[i++];
998  if (c == '+') {
999  xs = 1;
1000  c = cp[i++];
1001  } else if (c == '-') {
1002  xs = -1;
1003  c = cp[i++];
1004  }
1005  while (i <= ln) {
1006  if (c < '0' || c > '9') {
1007  break;
1008  }
1009  if ((xv = xv * 10 + c - '0') >= 1000) {
1010  return -1216;
1011  }
1012  c = cp[i++];
1013  }
1014  }
1015  if (i < ln) {
1016  if (cp[i] != ' ') {
1017  return -1213;
1018  }
1019  }
1020  if (xs == -1) {
1021  xv = -xv;
1022  }
1023  xv += j + 1;
1024  if (ps) {
1025  xv += ps + 1;
1026  }
1027  np->dec_ndgts = (j + 1) / 2;
1028  i = xv;
1029  if (i < 0) {
1030  i--;
1031  }
1032  np->dec_exp = i / 2;
1033  if ((xv & 1) == 0) {
1034  if ((j & 1) == 0) {
1035  np->dec_ndgts++;
1036  }
1037  j = 0;
1038  for (i = 0; i < ACCSIZE; i++) {
1039  xs = np->dec_dgts[i];
1040  np->dec_dgts[i] = xs / 10 + j;
1041  j = (xs % 10) * 10;
1042  }
1043  }
1044  i = dec_round (np, 0);
1045  np->dec_pos = ms;
1046  memcpy (rp, np, sizeof (dec_t));
1047  return i;
1048 }
1049 
1050 char *
1051 dececvt (dec_t *np, int dg, int *pt, int *sg)
1052 {
1053  return decefcvt (np, dg, pt, sg, 0);
1054 }
1055 
1056 char *
1057 decfcvt (dec_t *np, int dg, int *pt, int *sg)
1058 {
1059  return decefcvt (np, dg, pt, sg, 1);
1060 }
int deccvlong(long i, dec_t *dp)
Definition: isdecimal.c:386
char * dececvt(dec_t *np, int dg, int *pt, int *sg)
Definition: isdecimal.c:1051
int dectoint(dec_t *dp, int *ip)
Definition: isdecimal.c:372
static int dectoreal(dec_t *dp, double *dblp, int valid)
Definition: isdecimal.c:164
static char * decefcvt(dec_t *np, int dg, int *pt, int *sg, int fl)
Definition: isdecimal.c:203
short dec_pos
Definition: isdecimal.c:26
int decadd(dec_t *x, dec_t *y, dec_t *r)
Definition: isdecimal.c:541
int dectolong(dec_t *dp, long *ip)
Definition: isdecimal.c:399
int decmul(dec_t *x, dec_t *y, dec_t *r)
Definition: isdecimal.c:615
int lddecimal(unsigned char *cp, int len, dec_t *dp)
Definition: isdecimal.c:478
static void dectofix(dec_t *dp, long *ip)
Definition: isdecimal.c:113
char * decfcvt(dec_t *np, int dg, int *pt, int *sg)
Definition: isdecimal.c:1057
static int round100(unsigned char *cp, int len)
Definition: isdecimal.c:53
int decsub(dec_t *x, dec_t *y, dec_t *r)
Definition: isdecimal.c:522
int deccmp(dec_t *x, dec_t *y)
Definition: isdecimal.c:770
int deccvflt(float flt, dec_t *dp)
Definition: isdecimal.c:422
int deccvint(int i, dec_t *dp)
Definition: isdecimal.c:360
#define ACCSIZE
Definition: isdecimal.c:22
int dectoflt(dec_t *dp, float *fltp)
Definition: isdecimal.c:428
static int deccvreal(double dbl, dec_t *dp, int ndigits)
Definition: isdecimal.c:130
int dectoasc(dec_t *np, char *cp, int ln, int dg)
Definition: isdecimal.c:804
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 deccvasc(char *cp, int ln, dec_t *rp)
Definition: isdecimal.c:945
void stdecimal(dec_t *dp, unsigned char *cp, int len)
Definition: isdecimal.c:439
int deccvdbl(double dbl, dec_t *dp)
Definition: isdecimal.c:410
void deccopy(dec_t *src, dec_t *dst)
Definition: isdecimal.c:354
short dec_exp
Definition: isdecimal.c:25
int decdiv(dec_t *x, dec_t *y, dec_t *r)
Definition: isdecimal.c:654
int dectodbl(dec_t *dp, double *dblp)
Definition: isdecimal.c:416
static void comp100(unsigned char *cp, int count)
Definition: isdecimal.c:34
short dec_ndgts
Definition: isdecimal.c:27
static int deccvfix(long i, dec_t *dp)
Definition: isdecimal.c:81
char dec_dgts[(16+1)]
Definition: isdecimal.c:28
static int dec_round(struct decacc *s, int c)
Definition: isdecimal.c:278