ldecNumber

Check-in [acd5876087]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update to decNumber 3.37 Add random number generator Add pod documentation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:acd5876087859a445ec221f21c328311d65518a1
User & Date: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc 2007-01-17 04:55:17
Context
2007-06-18
21:32
Make context table weak on keys so threads are GC'd if cache off. Cache is off by default. Add test for thread memory leak. check-in: 55d4fc73d1 user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
2007-01-17
04:55
Update to decNumber 3.37 Add random number generator Add pod documentation check-in: acd5876087 user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
2006-10-02
20:00
Integrate Asko's generalized Makefile. Add __concat to decimal numbers. Update doco and README.txt check-in: 6225bab0ea user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.

28
29
30
31
32
33
34

35
36
37
38
39
40
41
...
108
109
110
111
112
113
114



115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
  BASE= /usr/local
  LUAINC= -I$(BASE)/include
  LUALIB= -L$(BASE)/lib -llua51
  LUAEXE= $(BASE)/bin/lua.exe
#  LUACMOD= $(BASE)/lib/lua/5.1/
#  Windows' LUA_CDIR is the Lua executable's directory...
  LUACMOD= $(BASE)/bin

endif

TMP=./tmp
DISTDIR=./archive

# OS detection
#
................................................................................

install:
	cp $T $(LUACMOD)

clean:
	rm -f $(OBJS) $T core core.* a.out




td:
	touch $(MYLIB)-$(VER).tar.gz

dist: vcheck
	echo 'Exporting...'
	mkdir -p $(TMP)
	mkdir -p $(DISTDIR)
	svn export -r HEAD . $(TMP)/$(MYLIB)-$(VER)
	cp -p version.h $(TMP)/$(MYLIB)-$(VER)
	cp -p doc/decNumber.pdf $(TMP)/$(MYLIB)-$(VER)/doc
	cp -p doc/ldecNumber.pdf $(TMP)/$(MYLIB)-$(VER)/doc

	echo 'Compressing...'
	tar -zcf $(TARFILE) -C $(TMP) $(MYLIB)-$(VER)
	rm -fr $(TMP)/$(MYLIB)-$(VER)
	echo 'Done.'

.PHONY: all vcheck test testall clean td dist install








>







 







>
>
>



|







>





|

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  BASE= /usr/local
  LUAINC= -I$(BASE)/include
  LUALIB= -L$(BASE)/lib -llua51
  LUAEXE= $(BASE)/bin/lua.exe
#  LUACMOD= $(BASE)/lib/lua/5.1/
#  Windows' LUA_CDIR is the Lua executable's directory...
  LUACMOD= $(BASE)/bin
  POD2HTML= perl -x -S doc/pod2html.pl
endif

TMP=./tmp
DISTDIR=./archive

# OS detection
#
................................................................................

install:
	cp $T $(LUACMOD)

clean:
	rm -f $(OBJS) $T core core.* a.out

html:
	$(POD2HTML) --title="Lua decNumber" --infile=doc/ldecNumber.pod --outfile=doc/ldecNumber.html

td:
	touch $(MYLIB)-$(VER).tar.gz

dist: vcheck html
	echo 'Exporting...'
	mkdir -p $(TMP)
	mkdir -p $(DISTDIR)
	svn export -r HEAD . $(TMP)/$(MYLIB)-$(VER)
	cp -p version.h $(TMP)/$(MYLIB)-$(VER)
	cp -p doc/decNumber.pdf $(TMP)/$(MYLIB)-$(VER)/doc
	cp -p doc/ldecNumber.pdf $(TMP)/$(MYLIB)-$(VER)/doc
	cp -p doc/ldecNumber.html $(TMP)/$(MYLIB)-$(VER)/doc
	echo 'Compressing...'
	tar -zcf $(TARFILE) -C $(TMP) $(MYLIB)-$(VER)
	rm -fr $(TMP)/$(MYLIB)-$(VER)
	echo 'Done.'

.PHONY: all vcheck test testall clean html td dist install

Changes to README.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
ldecNumber -- a Lua 5.1 wrapper for the decNumber Decimal Arithmetic package.

October 2, 2006

The Lua wrapper is
Copyright (c) 2006 Doug Currie, Londonderry, NH
All rights reserved.

The decNumber C library is
Copyright (c) 1995-2005 International Business Machines Corporation and others
All rights reserved.

The software and documentation is made available under the terms of the 


|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
ldecNumber -- a Lua 5.1 wrapper for the decNumber Decimal Arithmetic package.

January 15, 2007

The Lua wrapper is
Copyright (c) 2006-7 Doug Currie, Londonderry, NH
All rights reserved.

The decNumber C library is
Copyright (c) 1995-2005 International Business Machines Corporation and others
All rights reserved.

The software and documentation is made available under the terms of the 

Changes to decNumber/decDPD.h.

1
2
3
4
5
6
7
8
9
10
11
12
13


14

15
16
17




18
19
20
21
22
23
24

25
26
27
28
29
30
31
...
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
...
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
...
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
...
460
461
462
463
464
465
466
467






































































































































































































































































































































/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal <--> Densely Packed Decimal lookup tables           */
/* [Automatically generated -- do not edit.  2004.08.23]                    */
/* ------------------------------------------------------------------------ */
/* Copyright (c) IBM Corporation, 2000, 2004. All rights reserved.          */
/* ------------------------------------------------------------------------ */
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html     */
/*                                                                          */
/* This include file defines conversion tables for DPD, as follows.         */
/*                                                                          */
/*   uint16_t BCD2DPD[2458];     // BCD -> DPD (0x999 => 2457)              */
/*   uint16_t DPD2BCD[1024];     // DPD -> BCD (0x3FF => 0x999)             */
/*   uint16_t BIN2DPD[1000];     // BIN -> DPD (999 => 2457)                */


/*   uint16_t DPD2BIN[1024];     // DPD -> BIN (0x3FF => 999)               */

/*                                                                          */
/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */
/* in the table entry.                                                      */




/*                                                                          */
/* To use a table, its name, prefixed with DEC_, must be defined with a     */
/* value of 1 before this header file is included.  For example:            */
/*    #define DEC_BCD2DPD 1                                                 */
/* ------------------------------------------------------------------------ */
 
#if DEC_BCD2DPD==1

 
const uint16_t BCD2DPD[2458]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,    0,    0,    0,    0,    0,    0,   16,   17,   18,   19,   20, 
   21,   22,   23,   24,   25,    0,    0,    0,    0,    0,    0,   32,   33, 
   34,   35,   36,   37,   38,   39,   40,   41,    0,    0,    0,    0,    0, 
    0,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,    0,    0, 
    0,    0,    0,    0,   64,   65,   66,   67,   68,   69,   70,   71,   72, 
................................................................................
  236,  237,  492,  493,  748,  749, 1004, 1005,  942,  943,    0,    0,    0, 
    0,    0,    0,  252,  253,  508,  509,  764,  765, 1020, 1021,  958,  959, 
    0,    0,    0,    0,    0,    0,  142,  143,  398,  399,  654,  655,  910, 
  911,  238,  239,    0,    0,    0,    0,    0,    0,  158,  159,  414,  415, 
  670,  671,  926,  927,  254,  255};
#endif
 
#if DEC_DPD2BCD==1

 
const uint16_t DPD2BCD[1024]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,  128,  129, 2048, 2049, 2176, 2177,   16,   17,   18,   19,   20, 
   21,   22,   23,   24,   25,  144,  145, 2064, 2065, 2192, 2193,   32,   33, 
   34,   35,   36,   37,   38,   39,   40,   41,  130,  131, 2080, 2081, 2056, 
 2057,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,  146,  147, 
 2096, 2097, 2072, 2073,   64,   65,   66,   67,   68,   69,   70,   71,   72, 
................................................................................
 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 
 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891, 
 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904, 
 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423, 
 2456, 2457};
#endif
 
#if DEC_BIN2DPD==1

 
const uint16_t BIN2DPD[1000]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,   32, 
   33,   34,   35,   36,   37,   38,   39,   40,   41,   48,   49,   50,   51, 
   52,   53,   54,   55,   56,   57,   64,   65,   66,   67,   68,   69,   70, 
   71,   72,   73,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89, 
   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  112,  113,  114, 
................................................................................
  716,  717,  972,  973,  686,  687,  220,  221,  476,  477,  732,  733,  988, 
  989,  702,  703,  236,  237,  492,  493,  748,  749, 1004, 1005,  942,  943, 
  252,  253,  508,  509,  764,  765, 1020, 1021,  958,  959,  142,  143,  398, 
  399,  654,  655,  910,  911,  238,  239,  158,  159,  414,  415,  670,  671, 
  926,  927,  254,  255};
#endif 
 
#if DEC_DPD2BIN==1

 
const uint16_t DPD2BIN[1024]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,   80,   81,  800,  801,  880,  881,   10,   11,   12,   13,   14, 
   15,   16,   17,   18,   19,   90,   91,  810,  811,  890,  891,   20,   21, 
   22,   23,   24,   25,   26,   27,   28,   29,   82,   83,  820,  821,  808, 
  809,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   92,   93, 
  830,  831,  818,  819,   40,   41,   42,   43,   44,   45,   46,   47,   48, 
................................................................................
  937,  978,  979,  740,  741,  742,  743,  744,  745,  746,  747,  748,  749, 
  784,  785,  946,  947,  788,  789,  750,  751,  752,  753,  754,  755,  756, 
  757,  758,  759,  794,  795,  956,  957,  798,  799,  760,  761,  762,  763, 
  764,  765,  766,  767,  768,  769,  786,  787,  966,  967,  988,  989,  770, 
  771,  772,  773,  774,  775,  776,  777,  778,  779,  796,  797,  976,  977, 
  998,  999};
#endif
 








































































































































































































































































































































|

|






<

>
>

>


<
>
>
>
>






|
>







 







|
>







 







|
>







 







|
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal <--> Densely Packed Decimal lookup tables           */
/* [Automatically generated -- do not edit.  2006.11.09]                    */
/* ------------------------------------------------------------------------ */
/* Copyright (c) IBM Corporation, 2000, 2006. All rights reserved.          */
/* ------------------------------------------------------------------------ */
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html     */
/*                                                                          */
/* This include file defines conversion tables for DPD, as follows.         */
/*                                                                          */
/*   uint16_t BCD2DPD[2458];     // BCD -> DPD (0x999 => 2457)              */

/*   uint16_t BIN2DPD[1000];     // BIN -> DPD (999 => 2457)                */
/*   uint8_t  BIN2CHAR[4001];    // Bin -> CHAR (999 => '\3' '9' '9' '9')   */
/*   uint16_t DPD2BCD[1024];     // DPD -> BCD (0x3FF => 0x999)             */
/*   uint16_t DPD2BIN[1024];     // DPD -> BIN (0x3FF => 999)               */
/*   uint8_t  DPD2BCD8[4096];    // DPD -> bytes (x3FF => 9 9 9 3)          */
/*                                                                          */
/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */

/* in the table entry.  BIN2CHAR entries are a single byte length (0 for    */
/* value 0) followed by three digit characters; a trailing terminator is    */
/* included to allow 4-char moves always.  DPD2BCD8 entries are similar     */
/* with the three BCD8 digits followed by a one-byte length.                */
/*                                                                          */
/* To use a table, its name, prefixed with DEC_, must be defined with a     */
/* value of 1 before this header file is included.  For example:            */
/*    #define DEC_BCD2DPD 1                                                 */
/* ------------------------------------------------------------------------ */
 
#if DEC_BCD2DPD==1 && !defined(DECBCD2DPD)
#define DECBCD2DPD
 
const uint16_t BCD2DPD[2458]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,    0,    0,    0,    0,    0,    0,   16,   17,   18,   19,   20, 
   21,   22,   23,   24,   25,    0,    0,    0,    0,    0,    0,   32,   33, 
   34,   35,   36,   37,   38,   39,   40,   41,    0,    0,    0,    0,    0, 
    0,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,    0,    0, 
    0,    0,    0,    0,   64,   65,   66,   67,   68,   69,   70,   71,   72, 
................................................................................
  236,  237,  492,  493,  748,  749, 1004, 1005,  942,  943,    0,    0,    0, 
    0,    0,    0,  252,  253,  508,  509,  764,  765, 1020, 1021,  958,  959, 
    0,    0,    0,    0,    0,    0,  142,  143,  398,  399,  654,  655,  910, 
  911,  238,  239,    0,    0,    0,    0,    0,    0,  158,  159,  414,  415, 
  670,  671,  926,  927,  254,  255};
#endif
 
#if DEC_DPD2BCD==1 && !defined(DECDPD2BCD)
#define DECDPD2BCD
 
const uint16_t DPD2BCD[1024]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,  128,  129, 2048, 2049, 2176, 2177,   16,   17,   18,   19,   20, 
   21,   22,   23,   24,   25,  144,  145, 2064, 2065, 2192, 2193,   32,   33, 
   34,   35,   36,   37,   38,   39,   40,   41,  130,  131, 2080, 2081, 2056, 
 2057,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,  146,  147, 
 2096, 2097, 2072, 2073,   64,   65,   66,   67,   68,   69,   70,   71,   72, 
................................................................................
 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 
 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891, 
 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904, 
 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423, 
 2456, 2457};
#endif
 
#if DEC_BIN2DPD==1 && !defined(DECBIN2DPD)
#define DECBIN2DPD
 
const uint16_t BIN2DPD[1000]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,   32, 
   33,   34,   35,   36,   37,   38,   39,   40,   41,   48,   49,   50,   51, 
   52,   53,   54,   55,   56,   57,   64,   65,   66,   67,   68,   69,   70, 
   71,   72,   73,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89, 
   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  112,  113,  114, 
................................................................................
  716,  717,  972,  973,  686,  687,  220,  221,  476,  477,  732,  733,  988, 
  989,  702,  703,  236,  237,  492,  493,  748,  749, 1004, 1005,  942,  943, 
  252,  253,  508,  509,  764,  765, 1020, 1021,  958,  959,  142,  143,  398, 
  399,  654,  655,  910,  911,  238,  239,  158,  159,  414,  415,  670,  671, 
  926,  927,  254,  255};
#endif 
 
#if DEC_DPD2BIN==1 && !defined(DECDPD2BIN)
#define DECDPD2BIN
 
const uint16_t DPD2BIN[1024]={    0,    1,    2,    3,    4,    5,    6,    7, 
    8,    9,   80,   81,  800,  801,  880,  881,   10,   11,   12,   13,   14, 
   15,   16,   17,   18,   19,   90,   91,  810,  811,  890,  891,   20,   21, 
   22,   23,   24,   25,   26,   27,   28,   29,   82,   83,  820,  821,  808, 
  809,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   92,   93, 
  830,  831,  818,  819,   40,   41,   42,   43,   44,   45,   46,   47,   48, 
................................................................................
  937,  978,  979,  740,  741,  742,  743,  744,  745,  746,  747,  748,  749, 
  784,  785,  946,  947,  788,  789,  750,  751,  752,  753,  754,  755,  756, 
  757,  758,  759,  794,  795,  956,  957,  798,  799,  760,  761,  762,  763, 
  764,  765,  766,  767,  768,  769,  786,  787,  966,  967,  988,  989,  770, 
  771,  772,  773,  774,  775,  776,  777,  778,  779,  796,  797,  976,  977, 
  998,  999};
#endif
 
#if DEC_BIN2CHAR==1 && !defined(DECBIN2CHAR)
#define DECBIN2CHAR
 
const uint8_t BIN2CHAR[4001]={
 '\0','0','0','0', '\1','0','0','1', '\1','0','0','2', '\1','0','0','3', '\1','0','0','4', 
 '\1','0','0','5', '\1','0','0','6', '\1','0','0','7', '\1','0','0','8', '\1','0','0','9', 
 '\2','0','1','0', '\2','0','1','1', '\2','0','1','2', '\2','0','1','3', '\2','0','1','4', 
 '\2','0','1','5', '\2','0','1','6', '\2','0','1','7', '\2','0','1','8', '\2','0','1','9', 
 '\2','0','2','0', '\2','0','2','1', '\2','0','2','2', '\2','0','2','3', '\2','0','2','4', 
 '\2','0','2','5', '\2','0','2','6', '\2','0','2','7', '\2','0','2','8', '\2','0','2','9', 
 '\2','0','3','0', '\2','0','3','1', '\2','0','3','2', '\2','0','3','3', '\2','0','3','4', 
 '\2','0','3','5', '\2','0','3','6', '\2','0','3','7', '\2','0','3','8', '\2','0','3','9', 
 '\2','0','4','0', '\2','0','4','1', '\2','0','4','2', '\2','0','4','3', '\2','0','4','4', 
 '\2','0','4','5', '\2','0','4','6', '\2','0','4','7', '\2','0','4','8', '\2','0','4','9', 
 '\2','0','5','0', '\2','0','5','1', '\2','0','5','2', '\2','0','5','3', '\2','0','5','4', 
 '\2','0','5','5', '\2','0','5','6', '\2','0','5','7', '\2','0','5','8', '\2','0','5','9', 
 '\2','0','6','0', '\2','0','6','1', '\2','0','6','2', '\2','0','6','3', '\2','0','6','4', 
 '\2','0','6','5', '\2','0','6','6', '\2','0','6','7', '\2','0','6','8', '\2','0','6','9', 
 '\2','0','7','0', '\2','0','7','1', '\2','0','7','2', '\2','0','7','3', '\2','0','7','4', 
 '\2','0','7','5', '\2','0','7','6', '\2','0','7','7', '\2','0','7','8', '\2','0','7','9', 
 '\2','0','8','0', '\2','0','8','1', '\2','0','8','2', '\2','0','8','3', '\2','0','8','4', 
 '\2','0','8','5', '\2','0','8','6', '\2','0','8','7', '\2','0','8','8', '\2','0','8','9', 
 '\2','0','9','0', '\2','0','9','1', '\2','0','9','2', '\2','0','9','3', '\2','0','9','4', 
 '\2','0','9','5', '\2','0','9','6', '\2','0','9','7', '\2','0','9','8', '\2','0','9','9', 
 '\3','1','0','0', '\3','1','0','1', '\3','1','0','2', '\3','1','0','3', '\3','1','0','4', 
 '\3','1','0','5', '\3','1','0','6', '\3','1','0','7', '\3','1','0','8', '\3','1','0','9', 
 '\3','1','1','0', '\3','1','1','1', '\3','1','1','2', '\3','1','1','3', '\3','1','1','4', 
 '\3','1','1','5', '\3','1','1','6', '\3','1','1','7', '\3','1','1','8', '\3','1','1','9', 
 '\3','1','2','0', '\3','1','2','1', '\3','1','2','2', '\3','1','2','3', '\3','1','2','4', 
 '\3','1','2','5', '\3','1','2','6', '\3','1','2','7', '\3','1','2','8', '\3','1','2','9', 
 '\3','1','3','0', '\3','1','3','1', '\3','1','3','2', '\3','1','3','3', '\3','1','3','4', 
 '\3','1','3','5', '\3','1','3','6', '\3','1','3','7', '\3','1','3','8', '\3','1','3','9', 
 '\3','1','4','0', '\3','1','4','1', '\3','1','4','2', '\3','1','4','3', '\3','1','4','4', 
 '\3','1','4','5', '\3','1','4','6', '\3','1','4','7', '\3','1','4','8', '\3','1','4','9', 
 '\3','1','5','0', '\3','1','5','1', '\3','1','5','2', '\3','1','5','3', '\3','1','5','4', 
 '\3','1','5','5', '\3','1','5','6', '\3','1','5','7', '\3','1','5','8', '\3','1','5','9', 
 '\3','1','6','0', '\3','1','6','1', '\3','1','6','2', '\3','1','6','3', '\3','1','6','4', 
 '\3','1','6','5', '\3','1','6','6', '\3','1','6','7', '\3','1','6','8', '\3','1','6','9', 
 '\3','1','7','0', '\3','1','7','1', '\3','1','7','2', '\3','1','7','3', '\3','1','7','4', 
 '\3','1','7','5', '\3','1','7','6', '\3','1','7','7', '\3','1','7','8', '\3','1','7','9', 
 '\3','1','8','0', '\3','1','8','1', '\3','1','8','2', '\3','1','8','3', '\3','1','8','4', 
 '\3','1','8','5', '\3','1','8','6', '\3','1','8','7', '\3','1','8','8', '\3','1','8','9', 
 '\3','1','9','0', '\3','1','9','1', '\3','1','9','2', '\3','1','9','3', '\3','1','9','4', 
 '\3','1','9','5', '\3','1','9','6', '\3','1','9','7', '\3','1','9','8', '\3','1','9','9', 
 '\3','2','0','0', '\3','2','0','1', '\3','2','0','2', '\3','2','0','3', '\3','2','0','4', 
 '\3','2','0','5', '\3','2','0','6', '\3','2','0','7', '\3','2','0','8', '\3','2','0','9', 
 '\3','2','1','0', '\3','2','1','1', '\3','2','1','2', '\3','2','1','3', '\3','2','1','4', 
 '\3','2','1','5', '\3','2','1','6', '\3','2','1','7', '\3','2','1','8', '\3','2','1','9', 
 '\3','2','2','0', '\3','2','2','1', '\3','2','2','2', '\3','2','2','3', '\3','2','2','4', 
 '\3','2','2','5', '\3','2','2','6', '\3','2','2','7', '\3','2','2','8', '\3','2','2','9', 
 '\3','2','3','0', '\3','2','3','1', '\3','2','3','2', '\3','2','3','3', '\3','2','3','4', 
 '\3','2','3','5', '\3','2','3','6', '\3','2','3','7', '\3','2','3','8', '\3','2','3','9', 
 '\3','2','4','0', '\3','2','4','1', '\3','2','4','2', '\3','2','4','3', '\3','2','4','4', 
 '\3','2','4','5', '\3','2','4','6', '\3','2','4','7', '\3','2','4','8', '\3','2','4','9', 
 '\3','2','5','0', '\3','2','5','1', '\3','2','5','2', '\3','2','5','3', '\3','2','5','4', 
 '\3','2','5','5', '\3','2','5','6', '\3','2','5','7', '\3','2','5','8', '\3','2','5','9', 
 '\3','2','6','0', '\3','2','6','1', '\3','2','6','2', '\3','2','6','3', '\3','2','6','4', 
 '\3','2','6','5', '\3','2','6','6', '\3','2','6','7', '\3','2','6','8', '\3','2','6','9', 
 '\3','2','7','0', '\3','2','7','1', '\3','2','7','2', '\3','2','7','3', '\3','2','7','4', 
 '\3','2','7','5', '\3','2','7','6', '\3','2','7','7', '\3','2','7','8', '\3','2','7','9', 
 '\3','2','8','0', '\3','2','8','1', '\3','2','8','2', '\3','2','8','3', '\3','2','8','4', 
 '\3','2','8','5', '\3','2','8','6', '\3','2','8','7', '\3','2','8','8', '\3','2','8','9', 
 '\3','2','9','0', '\3','2','9','1', '\3','2','9','2', '\3','2','9','3', '\3','2','9','4', 
 '\3','2','9','5', '\3','2','9','6', '\3','2','9','7', '\3','2','9','8', '\3','2','9','9', 
 '\3','3','0','0', '\3','3','0','1', '\3','3','0','2', '\3','3','0','3', '\3','3','0','4', 
 '\3','3','0','5', '\3','3','0','6', '\3','3','0','7', '\3','3','0','8', '\3','3','0','9', 
 '\3','3','1','0', '\3','3','1','1', '\3','3','1','2', '\3','3','1','3', '\3','3','1','4', 
 '\3','3','1','5', '\3','3','1','6', '\3','3','1','7', '\3','3','1','8', '\3','3','1','9', 
 '\3','3','2','0', '\3','3','2','1', '\3','3','2','2', '\3','3','2','3', '\3','3','2','4', 
 '\3','3','2','5', '\3','3','2','6', '\3','3','2','7', '\3','3','2','8', '\3','3','2','9', 
 '\3','3','3','0', '\3','3','3','1', '\3','3','3','2', '\3','3','3','3', '\3','3','3','4', 
 '\3','3','3','5', '\3','3','3','6', '\3','3','3','7', '\3','3','3','8', '\3','3','3','9', 
 '\3','3','4','0', '\3','3','4','1', '\3','3','4','2', '\3','3','4','3', '\3','3','4','4', 
 '\3','3','4','5', '\3','3','4','6', '\3','3','4','7', '\3','3','4','8', '\3','3','4','9', 
 '\3','3','5','0', '\3','3','5','1', '\3','3','5','2', '\3','3','5','3', '\3','3','5','4', 
 '\3','3','5','5', '\3','3','5','6', '\3','3','5','7', '\3','3','5','8', '\3','3','5','9', 
 '\3','3','6','0', '\3','3','6','1', '\3','3','6','2', '\3','3','6','3', '\3','3','6','4', 
 '\3','3','6','5', '\3','3','6','6', '\3','3','6','7', '\3','3','6','8', '\3','3','6','9', 
 '\3','3','7','0', '\3','3','7','1', '\3','3','7','2', '\3','3','7','3', '\3','3','7','4', 
 '\3','3','7','5', '\3','3','7','6', '\3','3','7','7', '\3','3','7','8', '\3','3','7','9', 
 '\3','3','8','0', '\3','3','8','1', '\3','3','8','2', '\3','3','8','3', '\3','3','8','4', 
 '\3','3','8','5', '\3','3','8','6', '\3','3','8','7', '\3','3','8','8', '\3','3','8','9', 
 '\3','3','9','0', '\3','3','9','1', '\3','3','9','2', '\3','3','9','3', '\3','3','9','4', 
 '\3','3','9','5', '\3','3','9','6', '\3','3','9','7', '\3','3','9','8', '\3','3','9','9', 
 '\3','4','0','0', '\3','4','0','1', '\3','4','0','2', '\3','4','0','3', '\3','4','0','4', 
 '\3','4','0','5', '\3','4','0','6', '\3','4','0','7', '\3','4','0','8', '\3','4','0','9', 
 '\3','4','1','0', '\3','4','1','1', '\3','4','1','2', '\3','4','1','3', '\3','4','1','4', 
 '\3','4','1','5', '\3','4','1','6', '\3','4','1','7', '\3','4','1','8', '\3','4','1','9', 
 '\3','4','2','0', '\3','4','2','1', '\3','4','2','2', '\3','4','2','3', '\3','4','2','4', 
 '\3','4','2','5', '\3','4','2','6', '\3','4','2','7', '\3','4','2','8', '\3','4','2','9', 
 '\3','4','3','0', '\3','4','3','1', '\3','4','3','2', '\3','4','3','3', '\3','4','3','4', 
 '\3','4','3','5', '\3','4','3','6', '\3','4','3','7', '\3','4','3','8', '\3','4','3','9', 
 '\3','4','4','0', '\3','4','4','1', '\3','4','4','2', '\3','4','4','3', '\3','4','4','4', 
 '\3','4','4','5', '\3','4','4','6', '\3','4','4','7', '\3','4','4','8', '\3','4','4','9', 
 '\3','4','5','0', '\3','4','5','1', '\3','4','5','2', '\3','4','5','3', '\3','4','5','4', 
 '\3','4','5','5', '\3','4','5','6', '\3','4','5','7', '\3','4','5','8', '\3','4','5','9', 
 '\3','4','6','0', '\3','4','6','1', '\3','4','6','2', '\3','4','6','3', '\3','4','6','4', 
 '\3','4','6','5', '\3','4','6','6', '\3','4','6','7', '\3','4','6','8', '\3','4','6','9', 
 '\3','4','7','0', '\3','4','7','1', '\3','4','7','2', '\3','4','7','3', '\3','4','7','4', 
 '\3','4','7','5', '\3','4','7','6', '\3','4','7','7', '\3','4','7','8', '\3','4','7','9', 
 '\3','4','8','0', '\3','4','8','1', '\3','4','8','2', '\3','4','8','3', '\3','4','8','4', 
 '\3','4','8','5', '\3','4','8','6', '\3','4','8','7', '\3','4','8','8', '\3','4','8','9', 
 '\3','4','9','0', '\3','4','9','1', '\3','4','9','2', '\3','4','9','3', '\3','4','9','4', 
 '\3','4','9','5', '\3','4','9','6', '\3','4','9','7', '\3','4','9','8', '\3','4','9','9', 
 '\3','5','0','0', '\3','5','0','1', '\3','5','0','2', '\3','5','0','3', '\3','5','0','4', 
 '\3','5','0','5', '\3','5','0','6', '\3','5','0','7', '\3','5','0','8', '\3','5','0','9', 
 '\3','5','1','0', '\3','5','1','1', '\3','5','1','2', '\3','5','1','3', '\3','5','1','4', 
 '\3','5','1','5', '\3','5','1','6', '\3','5','1','7', '\3','5','1','8', '\3','5','1','9', 
 '\3','5','2','0', '\3','5','2','1', '\3','5','2','2', '\3','5','2','3', '\3','5','2','4', 
 '\3','5','2','5', '\3','5','2','6', '\3','5','2','7', '\3','5','2','8', '\3','5','2','9', 
 '\3','5','3','0', '\3','5','3','1', '\3','5','3','2', '\3','5','3','3', '\3','5','3','4', 
 '\3','5','3','5', '\3','5','3','6', '\3','5','3','7', '\3','5','3','8', '\3','5','3','9', 
 '\3','5','4','0', '\3','5','4','1', '\3','5','4','2', '\3','5','4','3', '\3','5','4','4', 
 '\3','5','4','5', '\3','5','4','6', '\3','5','4','7', '\3','5','4','8', '\3','5','4','9', 
 '\3','5','5','0', '\3','5','5','1', '\3','5','5','2', '\3','5','5','3', '\3','5','5','4', 
 '\3','5','5','5', '\3','5','5','6', '\3','5','5','7', '\3','5','5','8', '\3','5','5','9', 
 '\3','5','6','0', '\3','5','6','1', '\3','5','6','2', '\3','5','6','3', '\3','5','6','4', 
 '\3','5','6','5', '\3','5','6','6', '\3','5','6','7', '\3','5','6','8', '\3','5','6','9', 
 '\3','5','7','0', '\3','5','7','1', '\3','5','7','2', '\3','5','7','3', '\3','5','7','4', 
 '\3','5','7','5', '\3','5','7','6', '\3','5','7','7', '\3','5','7','8', '\3','5','7','9', 
 '\3','5','8','0', '\3','5','8','1', '\3','5','8','2', '\3','5','8','3', '\3','5','8','4', 
 '\3','5','8','5', '\3','5','8','6', '\3','5','8','7', '\3','5','8','8', '\3','5','8','9', 
 '\3','5','9','0', '\3','5','9','1', '\3','5','9','2', '\3','5','9','3', '\3','5','9','4', 
 '\3','5','9','5', '\3','5','9','6', '\3','5','9','7', '\3','5','9','8', '\3','5','9','9', 
 '\3','6','0','0', '\3','6','0','1', '\3','6','0','2', '\3','6','0','3', '\3','6','0','4', 
 '\3','6','0','5', '\3','6','0','6', '\3','6','0','7', '\3','6','0','8', '\3','6','0','9', 
 '\3','6','1','0', '\3','6','1','1', '\3','6','1','2', '\3','6','1','3', '\3','6','1','4', 
 '\3','6','1','5', '\3','6','1','6', '\3','6','1','7', '\3','6','1','8', '\3','6','1','9', 
 '\3','6','2','0', '\3','6','2','1', '\3','6','2','2', '\3','6','2','3', '\3','6','2','4', 
 '\3','6','2','5', '\3','6','2','6', '\3','6','2','7', '\3','6','2','8', '\3','6','2','9', 
 '\3','6','3','0', '\3','6','3','1', '\3','6','3','2', '\3','6','3','3', '\3','6','3','4', 
 '\3','6','3','5', '\3','6','3','6', '\3','6','3','7', '\3','6','3','8', '\3','6','3','9', 
 '\3','6','4','0', '\3','6','4','1', '\3','6','4','2', '\3','6','4','3', '\3','6','4','4', 
 '\3','6','4','5', '\3','6','4','6', '\3','6','4','7', '\3','6','4','8', '\3','6','4','9', 
 '\3','6','5','0', '\3','6','5','1', '\3','6','5','2', '\3','6','5','3', '\3','6','5','4', 
 '\3','6','5','5', '\3','6','5','6', '\3','6','5','7', '\3','6','5','8', '\3','6','5','9', 
 '\3','6','6','0', '\3','6','6','1', '\3','6','6','2', '\3','6','6','3', '\3','6','6','4', 
 '\3','6','6','5', '\3','6','6','6', '\3','6','6','7', '\3','6','6','8', '\3','6','6','9', 
 '\3','6','7','0', '\3','6','7','1', '\3','6','7','2', '\3','6','7','3', '\3','6','7','4', 
 '\3','6','7','5', '\3','6','7','6', '\3','6','7','7', '\3','6','7','8', '\3','6','7','9', 
 '\3','6','8','0', '\3','6','8','1', '\3','6','8','2', '\3','6','8','3', '\3','6','8','4', 
 '\3','6','8','5', '\3','6','8','6', '\3','6','8','7', '\3','6','8','8', '\3','6','8','9', 
 '\3','6','9','0', '\3','6','9','1', '\3','6','9','2', '\3','6','9','3', '\3','6','9','4', 
 '\3','6','9','5', '\3','6','9','6', '\3','6','9','7', '\3','6','9','8', '\3','6','9','9', 
 '\3','7','0','0', '\3','7','0','1', '\3','7','0','2', '\3','7','0','3', '\3','7','0','4', 
 '\3','7','0','5', '\3','7','0','6', '\3','7','0','7', '\3','7','0','8', '\3','7','0','9', 
 '\3','7','1','0', '\3','7','1','1', '\3','7','1','2', '\3','7','1','3', '\3','7','1','4', 
 '\3','7','1','5', '\3','7','1','6', '\3','7','1','7', '\3','7','1','8', '\3','7','1','9', 
 '\3','7','2','0', '\3','7','2','1', '\3','7','2','2', '\3','7','2','3', '\3','7','2','4', 
 '\3','7','2','5', '\3','7','2','6', '\3','7','2','7', '\3','7','2','8', '\3','7','2','9', 
 '\3','7','3','0', '\3','7','3','1', '\3','7','3','2', '\3','7','3','3', '\3','7','3','4', 
 '\3','7','3','5', '\3','7','3','6', '\3','7','3','7', '\3','7','3','8', '\3','7','3','9', 
 '\3','7','4','0', '\3','7','4','1', '\3','7','4','2', '\3','7','4','3', '\3','7','4','4', 
 '\3','7','4','5', '\3','7','4','6', '\3','7','4','7', '\3','7','4','8', '\3','7','4','9', 
 '\3','7','5','0', '\3','7','5','1', '\3','7','5','2', '\3','7','5','3', '\3','7','5','4', 
 '\3','7','5','5', '\3','7','5','6', '\3','7','5','7', '\3','7','5','8', '\3','7','5','9', 
 '\3','7','6','0', '\3','7','6','1', '\3','7','6','2', '\3','7','6','3', '\3','7','6','4', 
 '\3','7','6','5', '\3','7','6','6', '\3','7','6','7', '\3','7','6','8', '\3','7','6','9', 
 '\3','7','7','0', '\3','7','7','1', '\3','7','7','2', '\3','7','7','3', '\3','7','7','4', 
 '\3','7','7','5', '\3','7','7','6', '\3','7','7','7', '\3','7','7','8', '\3','7','7','9', 
 '\3','7','8','0', '\3','7','8','1', '\3','7','8','2', '\3','7','8','3', '\3','7','8','4', 
 '\3','7','8','5', '\3','7','8','6', '\3','7','8','7', '\3','7','8','8', '\3','7','8','9', 
 '\3','7','9','0', '\3','7','9','1', '\3','7','9','2', '\3','7','9','3', '\3','7','9','4', 
 '\3','7','9','5', '\3','7','9','6', '\3','7','9','7', '\3','7','9','8', '\3','7','9','9', 
 '\3','8','0','0', '\3','8','0','1', '\3','8','0','2', '\3','8','0','3', '\3','8','0','4', 
 '\3','8','0','5', '\3','8','0','6', '\3','8','0','7', '\3','8','0','8', '\3','8','0','9', 
 '\3','8','1','0', '\3','8','1','1', '\3','8','1','2', '\3','8','1','3', '\3','8','1','4', 
 '\3','8','1','5', '\3','8','1','6', '\3','8','1','7', '\3','8','1','8', '\3','8','1','9', 
 '\3','8','2','0', '\3','8','2','1', '\3','8','2','2', '\3','8','2','3', '\3','8','2','4', 
 '\3','8','2','5', '\3','8','2','6', '\3','8','2','7', '\3','8','2','8', '\3','8','2','9', 
 '\3','8','3','0', '\3','8','3','1', '\3','8','3','2', '\3','8','3','3', '\3','8','3','4', 
 '\3','8','3','5', '\3','8','3','6', '\3','8','3','7', '\3','8','3','8', '\3','8','3','9', 
 '\3','8','4','0', '\3','8','4','1', '\3','8','4','2', '\3','8','4','3', '\3','8','4','4', 
 '\3','8','4','5', '\3','8','4','6', '\3','8','4','7', '\3','8','4','8', '\3','8','4','9', 
 '\3','8','5','0', '\3','8','5','1', '\3','8','5','2', '\3','8','5','3', '\3','8','5','4', 
 '\3','8','5','5', '\3','8','5','6', '\3','8','5','7', '\3','8','5','8', '\3','8','5','9', 
 '\3','8','6','0', '\3','8','6','1', '\3','8','6','2', '\3','8','6','3', '\3','8','6','4', 
 '\3','8','6','5', '\3','8','6','6', '\3','8','6','7', '\3','8','6','8', '\3','8','6','9', 
 '\3','8','7','0', '\3','8','7','1', '\3','8','7','2', '\3','8','7','3', '\3','8','7','4', 
 '\3','8','7','5', '\3','8','7','6', '\3','8','7','7', '\3','8','7','8', '\3','8','7','9', 
 '\3','8','8','0', '\3','8','8','1', '\3','8','8','2', '\3','8','8','3', '\3','8','8','4', 
 '\3','8','8','5', '\3','8','8','6', '\3','8','8','7', '\3','8','8','8', '\3','8','8','9', 
 '\3','8','9','0', '\3','8','9','1', '\3','8','9','2', '\3','8','9','3', '\3','8','9','4', 
 '\3','8','9','5', '\3','8','9','6', '\3','8','9','7', '\3','8','9','8', '\3','8','9','9', 
 '\3','9','0','0', '\3','9','0','1', '\3','9','0','2', '\3','9','0','3', '\3','9','0','4', 
 '\3','9','0','5', '\3','9','0','6', '\3','9','0','7', '\3','9','0','8', '\3','9','0','9', 
 '\3','9','1','0', '\3','9','1','1', '\3','9','1','2', '\3','9','1','3', '\3','9','1','4', 
 '\3','9','1','5', '\3','9','1','6', '\3','9','1','7', '\3','9','1','8', '\3','9','1','9', 
 '\3','9','2','0', '\3','9','2','1', '\3','9','2','2', '\3','9','2','3', '\3','9','2','4', 
 '\3','9','2','5', '\3','9','2','6', '\3','9','2','7', '\3','9','2','8', '\3','9','2','9', 
 '\3','9','3','0', '\3','9','3','1', '\3','9','3','2', '\3','9','3','3', '\3','9','3','4', 
 '\3','9','3','5', '\3','9','3','6', '\3','9','3','7', '\3','9','3','8', '\3','9','3','9', 
 '\3','9','4','0', '\3','9','4','1', '\3','9','4','2', '\3','9','4','3', '\3','9','4','4', 
 '\3','9','4','5', '\3','9','4','6', '\3','9','4','7', '\3','9','4','8', '\3','9','4','9', 
 '\3','9','5','0', '\3','9','5','1', '\3','9','5','2', '\3','9','5','3', '\3','9','5','4', 
 '\3','9','5','5', '\3','9','5','6', '\3','9','5','7', '\3','9','5','8', '\3','9','5','9', 
 '\3','9','6','0', '\3','9','6','1', '\3','9','6','2', '\3','9','6','3', '\3','9','6','4', 
 '\3','9','6','5', '\3','9','6','6', '\3','9','6','7', '\3','9','6','8', '\3','9','6','9', 
 '\3','9','7','0', '\3','9','7','1', '\3','9','7','2', '\3','9','7','3', '\3','9','7','4', 
 '\3','9','7','5', '\3','9','7','6', '\3','9','7','7', '\3','9','7','8', '\3','9','7','9', 
 '\3','9','8','0', '\3','9','8','1', '\3','9','8','2', '\3','9','8','3', '\3','9','8','4', 
 '\3','9','8','5', '\3','9','8','6', '\3','9','8','7', '\3','9','8','8', '\3','9','8','9', 
 '\3','9','9','0', '\3','9','9','1', '\3','9','9','2', '\3','9','9','3', '\3','9','9','4', 
 '\3','9','9','5', '\3','9','9','6', '\3','9','9','7', '\3','9','9','8', '\3','9','9','9', '\0'};
#endif
 
#if DEC_DPD2BCD8==1 && !defined(DECDPD2BCD8)
#define DECDPD2BCD8
 
const uint8_t DPD2BCD8[4096]={
 0,0,0,0, 0,0,1,1, 0,0,2,1, 0,0,3,1, 0,0,4,1, 0,0,5,1, 0,0,6,1, 0,0,7,1, 0,0,8,1, 
 0,0,9,1, 0,8,0,2, 0,8,1,2, 8,0,0,3, 8,0,1,3, 8,8,0,3, 8,8,1,3, 0,1,0,2, 0,1,1,2, 
 0,1,2,2, 0,1,3,2, 0,1,4,2, 0,1,5,2, 0,1,6,2, 0,1,7,2, 0,1,8,2, 0,1,9,2, 0,9,0,2, 
 0,9,1,2, 8,1,0,3, 8,1,1,3, 8,9,0,3, 8,9,1,3, 0,2,0,2, 0,2,1,2, 0,2,2,2, 0,2,3,2, 
 0,2,4,2, 0,2,5,2, 0,2,6,2, 0,2,7,2, 0,2,8,2, 0,2,9,2, 0,8,2,2, 0,8,3,2, 8,2,0,3, 
 8,2,1,3, 8,0,8,3, 8,0,9,3, 0,3,0,2, 0,3,1,2, 0,3,2,2, 0,3,3,2, 0,3,4,2, 0,3,5,2, 
 0,3,6,2, 0,3,7,2, 0,3,8,2, 0,3,9,2, 0,9,2,2, 0,9,3,2, 8,3,0,3, 8,3,1,3, 8,1,8,3, 
 8,1,9,3, 0,4,0,2, 0,4,1,2, 0,4,2,2, 0,4,3,2, 0,4,4,2, 0,4,5,2, 0,4,6,2, 0,4,7,2, 
 0,4,8,2, 0,4,9,2, 0,8,4,2, 0,8,5,2, 8,4,0,3, 8,4,1,3, 0,8,8,2, 0,8,9,2, 0,5,0,2, 
 0,5,1,2, 0,5,2,2, 0,5,3,2, 0,5,4,2, 0,5,5,2, 0,5,6,2, 0,5,7,2, 0,5,8,2, 0,5,9,2, 
 0,9,4,2, 0,9,5,2, 8,5,0,3, 8,5,1,3, 0,9,8,2, 0,9,9,2, 0,6,0,2, 0,6,1,2, 0,6,2,2, 
 0,6,3,2, 0,6,4,2, 0,6,5,2, 0,6,6,2, 0,6,7,2, 0,6,8,2, 0,6,9,2, 0,8,6,2, 0,8,7,2, 
 8,6,0,3, 8,6,1,3, 8,8,8,3, 8,8,9,3, 0,7,0,2, 0,7,1,2, 0,7,2,2, 0,7,3,2, 0,7,4,2, 
 0,7,5,2, 0,7,6,2, 0,7,7,2, 0,7,8,2, 0,7,9,2, 0,9,6,2, 0,9,7,2, 8,7,0,3, 8,7,1,3, 
 8,9,8,3, 8,9,9,3, 1,0,0,3, 1,0,1,3, 1,0,2,3, 1,0,3,3, 1,0,4,3, 1,0,5,3, 1,0,6,3, 
 1,0,7,3, 1,0,8,3, 1,0,9,3, 1,8,0,3, 1,8,1,3, 9,0,0,3, 9,0,1,3, 9,8,0,3, 9,8,1,3, 
 1,1,0,3, 1,1,1,3, 1,1,2,3, 1,1,3,3, 1,1,4,3, 1,1,5,3, 1,1,6,3, 1,1,7,3, 1,1,8,3, 
 1,1,9,3, 1,9,0,3, 1,9,1,3, 9,1,0,3, 9,1,1,3, 9,9,0,3, 9,9,1,3, 1,2,0,3, 1,2,1,3, 
 1,2,2,3, 1,2,3,3, 1,2,4,3, 1,2,5,3, 1,2,6,3, 1,2,7,3, 1,2,8,3, 1,2,9,3, 1,8,2,3, 
 1,8,3,3, 9,2,0,3, 9,2,1,3, 9,0,8,3, 9,0,9,3, 1,3,0,3, 1,3,1,3, 1,3,2,3, 1,3,3,3, 
 1,3,4,3, 1,3,5,3, 1,3,6,3, 1,3,7,3, 1,3,8,3, 1,3,9,3, 1,9,2,3, 1,9,3,3, 9,3,0,3, 
 9,3,1,3, 9,1,8,3, 9,1,9,3, 1,4,0,3, 1,4,1,3, 1,4,2,3, 1,4,3,3, 1,4,4,3, 1,4,5,3, 
 1,4,6,3, 1,4,7,3, 1,4,8,3, 1,4,9,3, 1,8,4,3, 1,8,5,3, 9,4,0,3, 9,4,1,3, 1,8,8,3, 
 1,8,9,3, 1,5,0,3, 1,5,1,3, 1,5,2,3, 1,5,3,3, 1,5,4,3, 1,5,5,3, 1,5,6,3, 1,5,7,3, 
 1,5,8,3, 1,5,9,3, 1,9,4,3, 1,9,5,3, 9,5,0,3, 9,5,1,3, 1,9,8,3, 1,9,9,3, 1,6,0,3, 
 1,6,1,3, 1,6,2,3, 1,6,3,3, 1,6,4,3, 1,6,5,3, 1,6,6,3, 1,6,7,3, 1,6,8,3, 1,6,9,3, 
 1,8,6,3, 1,8,7,3, 9,6,0,3, 9,6,1,3, 9,8,8,3, 9,8,9,3, 1,7,0,3, 1,7,1,3, 1,7,2,3, 
 1,7,3,3, 1,7,4,3, 1,7,5,3, 1,7,6,3, 1,7,7,3, 1,7,8,3, 1,7,9,3, 1,9,6,3, 1,9,7,3, 
 9,7,0,3, 9,7,1,3, 9,9,8,3, 9,9,9,3, 2,0,0,3, 2,0,1,3, 2,0,2,3, 2,0,3,3, 2,0,4,3, 
 2,0,5,3, 2,0,6,3, 2,0,7,3, 2,0,8,3, 2,0,9,3, 2,8,0,3, 2,8,1,3, 8,0,2,3, 8,0,3,3, 
 8,8,2,3, 8,8,3,3, 2,1,0,3, 2,1,1,3, 2,1,2,3, 2,1,3,3, 2,1,4,3, 2,1,5,3, 2,1,6,3, 
 2,1,7,3, 2,1,8,3, 2,1,9,3, 2,9,0,3, 2,9,1,3, 8,1,2,3, 8,1,3,3, 8,9,2,3, 8,9,3,3, 
 2,2,0,3, 2,2,1,3, 2,2,2,3, 2,2,3,3, 2,2,4,3, 2,2,5,3, 2,2,6,3, 2,2,7,3, 2,2,8,3, 
 2,2,9,3, 2,8,2,3, 2,8,3,3, 8,2,2,3, 8,2,3,3, 8,2,8,3, 8,2,9,3, 2,3,0,3, 2,3,1,3, 
 2,3,2,3, 2,3,3,3, 2,3,4,3, 2,3,5,3, 2,3,6,3, 2,3,7,3, 2,3,8,3, 2,3,9,3, 2,9,2,3, 
 2,9,3,3, 8,3,2,3, 8,3,3,3, 8,3,8,3, 8,3,9,3, 2,4,0,3, 2,4,1,3, 2,4,2,3, 2,4,3,3, 
 2,4,4,3, 2,4,5,3, 2,4,6,3, 2,4,7,3, 2,4,8,3, 2,4,9,3, 2,8,4,3, 2,8,5,3, 8,4,2,3, 
 8,4,3,3, 2,8,8,3, 2,8,9,3, 2,5,0,3, 2,5,1,3, 2,5,2,3, 2,5,3,3, 2,5,4,3, 2,5,5,3, 
 2,5,6,3, 2,5,7,3, 2,5,8,3, 2,5,9,3, 2,9,4,3, 2,9,5,3, 8,5,2,3, 8,5,3,3, 2,9,8,3, 
 2,9,9,3, 2,6,0,3, 2,6,1,3, 2,6,2,3, 2,6,3,3, 2,6,4,3, 2,6,5,3, 2,6,6,3, 2,6,7,3, 
 2,6,8,3, 2,6,9,3, 2,8,6,3, 2,8,7,3, 8,6,2,3, 8,6,3,3, 8,8,8,3, 8,8,9,3, 2,7,0,3, 
 2,7,1,3, 2,7,2,3, 2,7,3,3, 2,7,4,3, 2,7,5,3, 2,7,6,3, 2,7,7,3, 2,7,8,3, 2,7,9,3, 
 2,9,6,3, 2,9,7,3, 8,7,2,3, 8,7,3,3, 8,9,8,3, 8,9,9,3, 3,0,0,3, 3,0,1,3, 3,0,2,3, 
 3,0,3,3, 3,0,4,3, 3,0,5,3, 3,0,6,3, 3,0,7,3, 3,0,8,3, 3,0,9,3, 3,8,0,3, 3,8,1,3, 
 9,0,2,3, 9,0,3,3, 9,8,2,3, 9,8,3,3, 3,1,0,3, 3,1,1,3, 3,1,2,3, 3,1,3,3, 3,1,4,3, 
 3,1,5,3, 3,1,6,3, 3,1,7,3, 3,1,8,3, 3,1,9,3, 3,9,0,3, 3,9,1,3, 9,1,2,3, 9,1,3,3, 
 9,9,2,3, 9,9,3,3, 3,2,0,3, 3,2,1,3, 3,2,2,3, 3,2,3,3, 3,2,4,3, 3,2,5,3, 3,2,6,3, 
 3,2,7,3, 3,2,8,3, 3,2,9,3, 3,8,2,3, 3,8,3,3, 9,2,2,3, 9,2,3,3, 9,2,8,3, 9,2,9,3, 
 3,3,0,3, 3,3,1,3, 3,3,2,3, 3,3,3,3, 3,3,4,3, 3,3,5,3, 3,3,6,3, 3,3,7,3, 3,3,8,3, 
 3,3,9,3, 3,9,2,3, 3,9,3,3, 9,3,2,3, 9,3,3,3, 9,3,8,3, 9,3,9,3, 3,4,0,3, 3,4,1,3, 
 3,4,2,3, 3,4,3,3, 3,4,4,3, 3,4,5,3, 3,4,6,3, 3,4,7,3, 3,4,8,3, 3,4,9,3, 3,8,4,3, 
 3,8,5,3, 9,4,2,3, 9,4,3,3, 3,8,8,3, 3,8,9,3, 3,5,0,3, 3,5,1,3, 3,5,2,3, 3,5,3,3, 
 3,5,4,3, 3,5,5,3, 3,5,6,3, 3,5,7,3, 3,5,8,3, 3,5,9,3, 3,9,4,3, 3,9,5,3, 9,5,2,3, 
 9,5,3,3, 3,9,8,3, 3,9,9,3, 3,6,0,3, 3,6,1,3, 3,6,2,3, 3,6,3,3, 3,6,4,3, 3,6,5,3, 
 3,6,6,3, 3,6,7,3, 3,6,8,3, 3,6,9,3, 3,8,6,3, 3,8,7,3, 9,6,2,3, 9,6,3,3, 9,8,8,3, 
 9,8,9,3, 3,7,0,3, 3,7,1,3, 3,7,2,3, 3,7,3,3, 3,7,4,3, 3,7,5,3, 3,7,6,3, 3,7,7,3, 
 3,7,8,3, 3,7,9,3, 3,9,6,3, 3,9,7,3, 9,7,2,3, 9,7,3,3, 9,9,8,3, 9,9,9,3, 4,0,0,3, 
 4,0,1,3, 4,0,2,3, 4,0,3,3, 4,0,4,3, 4,0,5,3, 4,0,6,3, 4,0,7,3, 4,0,8,3, 4,0,9,3, 
 4,8,0,3, 4,8,1,3, 8,0,4,3, 8,0,5,3, 8,8,4,3, 8,8,5,3, 4,1,0,3, 4,1,1,3, 4,1,2,3, 
 4,1,3,3, 4,1,4,3, 4,1,5,3, 4,1,6,3, 4,1,7,3, 4,1,8,3, 4,1,9,3, 4,9,0,3, 4,9,1,3, 
 8,1,4,3, 8,1,5,3, 8,9,4,3, 8,9,5,3, 4,2,0,3, 4,2,1,3, 4,2,2,3, 4,2,3,3, 4,2,4,3, 
 4,2,5,3, 4,2,6,3, 4,2,7,3, 4,2,8,3, 4,2,9,3, 4,8,2,3, 4,8,3,3, 8,2,4,3, 8,2,5,3, 
 8,4,8,3, 8,4,9,3, 4,3,0,3, 4,3,1,3, 4,3,2,3, 4,3,3,3, 4,3,4,3, 4,3,5,3, 4,3,6,3, 
 4,3,7,3, 4,3,8,3, 4,3,9,3, 4,9,2,3, 4,9,3,3, 8,3,4,3, 8,3,5,3, 8,5,8,3, 8,5,9,3, 
 4,4,0,3, 4,4,1,3, 4,4,2,3, 4,4,3,3, 4,4,4,3, 4,4,5,3, 4,4,6,3, 4,4,7,3, 4,4,8,3, 
 4,4,9,3, 4,8,4,3, 4,8,5,3, 8,4,4,3, 8,4,5,3, 4,8,8,3, 4,8,9,3, 4,5,0,3, 4,5,1,3, 
 4,5,2,3, 4,5,3,3, 4,5,4,3, 4,5,5,3, 4,5,6,3, 4,5,7,3, 4,5,8,3, 4,5,9,3, 4,9,4,3, 
 4,9,5,3, 8,5,4,3, 8,5,5,3, 4,9,8,3, 4,9,9,3, 4,6,0,3, 4,6,1,3, 4,6,2,3, 4,6,3,3, 
 4,6,4,3, 4,6,5,3, 4,6,6,3, 4,6,7,3, 4,6,8,3, 4,6,9,3, 4,8,6,3, 4,8,7,3, 8,6,4,3, 
 8,6,5,3, 8,8,8,3, 8,8,9,3, 4,7,0,3, 4,7,1,3, 4,7,2,3, 4,7,3,3, 4,7,4,3, 4,7,5,3, 
 4,7,6,3, 4,7,7,3, 4,7,8,3, 4,7,9,3, 4,9,6,3, 4,9,7,3, 8,7,4,3, 8,7,5,3, 8,9,8,3, 
 8,9,9,3, 5,0,0,3, 5,0,1,3, 5,0,2,3, 5,0,3,3, 5,0,4,3, 5,0,5,3, 5,0,6,3, 5,0,7,3, 
 5,0,8,3, 5,0,9,3, 5,8,0,3, 5,8,1,3, 9,0,4,3, 9,0,5,3, 9,8,4,3, 9,8,5,3, 5,1,0,3, 
 5,1,1,3, 5,1,2,3, 5,1,3,3, 5,1,4,3, 5,1,5,3, 5,1,6,3, 5,1,7,3, 5,1,8,3, 5,1,9,3, 
 5,9,0,3, 5,9,1,3, 9,1,4,3, 9,1,5,3, 9,9,4,3, 9,9,5,3, 5,2,0,3, 5,2,1,3, 5,2,2,3, 
 5,2,3,3, 5,2,4,3, 5,2,5,3, 5,2,6,3, 5,2,7,3, 5,2,8,3, 5,2,9,3, 5,8,2,3, 5,8,3,3, 
 9,2,4,3, 9,2,5,3, 9,4,8,3, 9,4,9,3, 5,3,0,3, 5,3,1,3, 5,3,2,3, 5,3,3,3, 5,3,4,3, 
 5,3,5,3, 5,3,6,3, 5,3,7,3, 5,3,8,3, 5,3,9,3, 5,9,2,3, 5,9,3,3, 9,3,4,3, 9,3,5,3, 
 9,5,8,3, 9,5,9,3, 5,4,0,3, 5,4,1,3, 5,4,2,3, 5,4,3,3, 5,4,4,3, 5,4,5,3, 5,4,6,3, 
 5,4,7,3, 5,4,8,3, 5,4,9,3, 5,8,4,3, 5,8,5,3, 9,4,4,3, 9,4,5,3, 5,8,8,3, 5,8,9,3, 
 5,5,0,3, 5,5,1,3, 5,5,2,3, 5,5,3,3, 5,5,4,3, 5,5,5,3, 5,5,6,3, 5,5,7,3, 5,5,8,3, 
 5,5,9,3, 5,9,4,3, 5,9,5,3, 9,5,4,3, 9,5,5,3, 5,9,8,3, 5,9,9,3, 5,6,0,3, 5,6,1,3, 
 5,6,2,3, 5,6,3,3, 5,6,4,3, 5,6,5,3, 5,6,6,3, 5,6,7,3, 5,6,8,3, 5,6,9,3, 5,8,6,3, 
 5,8,7,3, 9,6,4,3, 9,6,5,3, 9,8,8,3, 9,8,9,3, 5,7,0,3, 5,7,1,3, 5,7,2,3, 5,7,3,3, 
 5,7,4,3, 5,7,5,3, 5,7,6,3, 5,7,7,3, 5,7,8,3, 5,7,9,3, 5,9,6,3, 5,9,7,3, 9,7,4,3, 
 9,7,5,3, 9,9,8,3, 9,9,9,3, 6,0,0,3, 6,0,1,3, 6,0,2,3, 6,0,3,3, 6,0,4,3, 6,0,5,3, 
 6,0,6,3, 6,0,7,3, 6,0,8,3, 6,0,9,3, 6,8,0,3, 6,8,1,3, 8,0,6,3, 8,0,7,3, 8,8,6,3, 
 8,8,7,3, 6,1,0,3, 6,1,1,3, 6,1,2,3, 6,1,3,3, 6,1,4,3, 6,1,5,3, 6,1,6,3, 6,1,7,3, 
 6,1,8,3, 6,1,9,3, 6,9,0,3, 6,9,1,3, 8,1,6,3, 8,1,7,3, 8,9,6,3, 8,9,7,3, 6,2,0,3, 
 6,2,1,3, 6,2,2,3, 6,2,3,3, 6,2,4,3, 6,2,5,3, 6,2,6,3, 6,2,7,3, 6,2,8,3, 6,2,9,3, 
 6,8,2,3, 6,8,3,3, 8,2,6,3, 8,2,7,3, 8,6,8,3, 8,6,9,3, 6,3,0,3, 6,3,1,3, 6,3,2,3, 
 6,3,3,3, 6,3,4,3, 6,3,5,3, 6,3,6,3, 6,3,7,3, 6,3,8,3, 6,3,9,3, 6,9,2,3, 6,9,3,3, 
 8,3,6,3, 8,3,7,3, 8,7,8,3, 8,7,9,3, 6,4,0,3, 6,4,1,3, 6,4,2,3, 6,4,3,3, 6,4,4,3, 
 6,4,5,3, 6,4,6,3, 6,4,7,3, 6,4,8,3, 6,4,9,3, 6,8,4,3, 6,8,5,3, 8,4,6,3, 8,4,7,3, 
 6,8,8,3, 6,8,9,3, 6,5,0,3, 6,5,1,3, 6,5,2,3, 6,5,3,3, 6,5,4,3, 6,5,5,3, 6,5,6,3, 
 6,5,7,3, 6,5,8,3, 6,5,9,3, 6,9,4,3, 6,9,5,3, 8,5,6,3, 8,5,7,3, 6,9,8,3, 6,9,9,3, 
 6,6,0,3, 6,6,1,3, 6,6,2,3, 6,6,3,3, 6,6,4,3, 6,6,5,3, 6,6,6,3, 6,6,7,3, 6,6,8,3, 
 6,6,9,3, 6,8,6,3, 6,8,7,3, 8,6,6,3, 8,6,7,3, 8,8,8,3, 8,8,9,3, 6,7,0,3, 6,7,1,3, 
 6,7,2,3, 6,7,3,3, 6,7,4,3, 6,7,5,3, 6,7,6,3, 6,7,7,3, 6,7,8,3, 6,7,9,3, 6,9,6,3, 
 6,9,7,3, 8,7,6,3, 8,7,7,3, 8,9,8,3, 8,9,9,3, 7,0,0,3, 7,0,1,3, 7,0,2,3, 7,0,3,3, 
 7,0,4,3, 7,0,5,3, 7,0,6,3, 7,0,7,3, 7,0,8,3, 7,0,9,3, 7,8,0,3, 7,8,1,3, 9,0,6,3, 
 9,0,7,3, 9,8,6,3, 9,8,7,3, 7,1,0,3, 7,1,1,3, 7,1,2,3, 7,1,3,3, 7,1,4,3, 7,1,5,3, 
 7,1,6,3, 7,1,7,3, 7,1,8,3, 7,1,9,3, 7,9,0,3, 7,9,1,3, 9,1,6,3, 9,1,7,3, 9,9,6,3, 
 9,9,7,3, 7,2,0,3, 7,2,1,3, 7,2,2,3, 7,2,3,3, 7,2,4,3, 7,2,5,3, 7,2,6,3, 7,2,7,3, 
 7,2,8,3, 7,2,9,3, 7,8,2,3, 7,8,3,3, 9,2,6,3, 9,2,7,3, 9,6,8,3, 9,6,9,3, 7,3,0,3, 
 7,3,1,3, 7,3,2,3, 7,3,3,3, 7,3,4,3, 7,3,5,3, 7,3,6,3, 7,3,7,3, 7,3,8,3, 7,3,9,3, 
 7,9,2,3, 7,9,3,3, 9,3,6,3, 9,3,7,3, 9,7,8,3, 9,7,9,3, 7,4,0,3, 7,4,1,3, 7,4,2,3, 
 7,4,3,3, 7,4,4,3, 7,4,5,3, 7,4,6,3, 7,4,7,3, 7,4,8,3, 7,4,9,3, 7,8,4,3, 7,8,5,3, 
 9,4,6,3, 9,4,7,3, 7,8,8,3, 7,8,9,3, 7,5,0,3, 7,5,1,3, 7,5,2,3, 7,5,3,3, 7,5,4,3, 
 7,5,5,3, 7,5,6,3, 7,5,7,3, 7,5,8,3, 7,5,9,3, 7,9,4,3, 7,9,5,3, 9,5,6,3, 9,5,7,3, 
 7,9,8,3, 7,9,9,3, 7,6,0,3, 7,6,1,3, 7,6,2,3, 7,6,3,3, 7,6,4,3, 7,6,5,3, 7,6,6,3, 
 7,6,7,3, 7,6,8,3, 7,6,9,3, 7,8,6,3, 7,8,7,3, 9,6,6,3, 9,6,7,3, 9,8,8,3, 9,8,9,3, 
 7,7,0,3, 7,7,1,3, 7,7,2,3, 7,7,3,3, 7,7,4,3, 7,7,5,3, 7,7,6,3, 7,7,7,3, 7,7,8,3, 
 7,7,9,3, 7,9,6,3, 7,9,7,3, 9,7,6,3, 9,7,7,3, 9,9,8,3, 9,9,9,3};
#endif
 

Changes to decNumber/decNumber.c.

178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
...
278
279
280
281
282
283
284
285
286
287
288
289



290
291
292
293

294
295
296
297
298
299
300
...
399
400
401
402
403
404
405

406
407
408
409
410
411
412
...
432
433
434
435
436
437
438
439
440




441
442
443
444
445
446
447
...
598
599
600
601
602
603
604



605
606
607
608
609
610
611
...
619
620
621
622
623
624
625



626
627
628
629
630
631
632
...
680
681
682
683
684
685
686



687
688
689
690
691
692
693
...
762
763
764
765
766
767
768



769
770
771
772
773
774
775
...
829
830
831
832
833
834
835



836
837
838
839
840
841
842
...
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
...
993
994
995
996
997
998
999



1000
1001
1002
1003
1004
1005
1006
....
1013
1014
1015
1016
1017
1018
1019



1020
1021
1022
1023
1024
1025
1026
....
1033
1034
1035
1036
1037
1038
1039



1040
1041
1042
1043
1044
1045
1046
....
1062
1063
1064
1065
1066
1067
1068



1069
1070
1071
1072
1073
1074
1075
....
1093
1094
1095
1096
1097
1098
1099



1100
1101
1102
1103
1104
1105
1106
....
1113
1114
1115
1116
1117
1118
1119



1120
1121
1122
1123
1124
1125
1126
....
1519
1520
1521
1522
1523
1524
1525



1526
1527
1528
1529
1530
1531
1532
....
1591
1592
1593
1594
1595
1596
1597



1598
1599
1600
1601
1602
1603
1604
....
1611
1612
1613
1614
1615
1616
1617



1618
1619
1620
1621
1622
1623
1624
....
1936
1937
1938
1939
1940
1941
1942
1943

1944
1945
1946
1947
1948
1949
1950
....
1959
1960
1961
1962
1963
1964
1965

1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
....
1977
1978
1979
1980
1981
1982
1983










1984
1985
1986
1987
1988
1989
1990
1991
1992
1993



1994
1995
1996
1997
1998
1999
2000
....
2008
2009
2010
2011
2012
2013
2014



2015
2016
2017
2018
2019
2020
2021
....
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
....
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
....
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
....
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
....
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
....
6476
6477
6478
6479
6480
6481
6482






















6483
6484
6485
6486
6487
6488
6489
#define COMPMIN   0x03             // ..
#define COMPTOTAL 0x04             // ..
#define COMPNAN   0x05             // .. [NaN processing]

#define DEC_sNaN     0x40000000    // local status: sNaN signal
#define BADINT  (Int)0x80000000    // most-negative Int; error indicator
// Next two indicate an integer >= 10**6, and its parity (bottom bit)
#define BIGODD  (Int)0x80000001
#define BIGEVEN (Int)0x80000001


static Unit uarrone[1]={1};   // Unit array of 1, used for incrementing

/* Granularity-dependent code */
#if DECDPUN<=4
  #define eInt  Int           // extended integer
  #define ueInt uInt          // unsigned extended integer
................................................................................
// To check for memory leaks, the decAllocBytes variable must be
// checked to be 0 at appropriate times (e.g., after the test
// harness completes a set of tests).  This checking may be unreliable
// if the testing is done in a multi-thread environment.
#endif

#if DECCHECK
// Optional operand checking routines.  Enabling these means that
// decNumber and decContext operands to operator routines are checked
// for correctness.  This roughly doubles the execution time of the
// fastest routines (and adds 600+ bytes), so should not normally be
// used in 'production'.



#define DECUNUSED (void *)(0xffffffff)
static Flag decCheckOperands(decNumber *, const decNumber *,
                             const decNumber *, decContext *);
static Flag decCheckNumber(const decNumber *, decContext *);

#endif

#if DECTRACE || DECCHECK
// Optional trace/debugging routines (may or may not be used)
void decNumberShow(const decNumber *);  // displays the components of a number
static void decDumpAr(char, const Unit *, Int);
#endif
................................................................................
      status=DEC_Conversion_syntax;// assume the worst
      if (*c=='\0') break;         // and no more to come...
      #if DECSUBSET
      // if subset then infinities and NaNs are not allowed
      if (!set->extended) break;   // hopeless
      #endif
      // Infinities and NaNs are possible, here

      decNumberZero(dn);           // be optimistic
      if (decBiStr(c, "infinity", "INFINITY")
       || decBiStr(c, "inf", "INF")) {
        dn->bits=bits | DECINF;
        status=0;                  // is OK
        break; // all done
        }
................................................................................
        }
      // something other than 0s; setup last and d as usual [no dots]
      for (c=cfirst;; c++, d++) {
        if (*c<'0' || *c>'9') break; // test for Arabic digit
        last=c;
        }
      if (*c!='\0') break;         // not all digits
      if (d>set->digits) break;    // too many digits
      // [NB: payload in a decNumber can be full length]




      // good; drop through to convert the integer to coefficient
      status=0;                    // syntax is OK
      bits=dn->bits;               // for copy-back
      } // last==NULL

     else if (*c!='\0') {          // more to process...
      // had some digits; exponent is only valid sequence now
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // set 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberAbs

/* ------------------------------------------------------------------ */
/* decNumberAdd -- add two Numbers                                    */
/*                                                                    */
/*   This computes C = A + B                                          */
................................................................................
/* ------------------------------------------------------------------ */
/* This just calls the routine shared with Subtract                   */
decNumber * decNumberAdd(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decAddOp(res, lhs, rhs, set, 0, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberAdd

/* ------------------------------------------------------------------ */
/* decNumberCompare -- compare two Numbers                            */
/*                                                                    */
/*   This computes C = A ? B                                          */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,
                            const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberDivide

/* ------------------------------------------------------------------ */
/* decNumberDivideInteger -- divide and return integer quotient       */
/*                                                                    */
/*   This computes C = A # B, where # is the integer divide operator  */
................................................................................
    } while(0);                         // end protected

  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberExp

/* ------------------------------------------------------------------ */
/* decNumberLn -- natural logarithm                                   */
/*                                                                    */
/*   This computes C = ln(A)                                          */
................................................................................
    } while(0);                         // end protected

  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberLn

/* ------------------------------------------------------------------ */
/* decNumberLog10 -- logarithm in base 10                             */
/*                                                                    */
/*   This computes C = log10(A)                                       */
................................................................................
    aset.digits=p;                      // as calculated
    aset.emax=DEC_MAX_MATH;             // usual bounds
    aset.emin=-DEC_MAX_MATH;            // ..
    aset.clamp=0;                       // and no concrete format
    decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)

    // skip the division if the result so far is infinite, NaN, or
    // zero, or there was an error
    if (status&DEC_NaNs) break;         // Error
    if (a->bits&DECSPECIAL || ISZERO(a)) {
      decNumberCopy(res, a);            // [will fit]
      break;}

    // for ln(10) an extra 3 digits of precision are needed
    p=set->digits+3;
    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
................................................................................
  if (allocbufa!=NULL) free(allocbufa); // drop any storage used
  if (allocbufb!=NULL) free(allocbufb); // ..
  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // ..
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberLog10

/* ------------------------------------------------------------------ */
/* decNumberMax -- compare two Numbers and return the maximum         */
/*                                                                    */
/*   This computes C = A ? B, returning the maximum or A if equal     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberMax

/* ------------------------------------------------------------------ */
/* decNumberMin -- compare two Numbers and return the minimum         */
/*                                                                    */
/*   This computes C = A ? B, returning the minimum or A if equal     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberMin

/* ------------------------------------------------------------------ */
/* decNumberMinus -- prefix minus operator                            */
/*                                                                    */
/*   This computes C = 0 - A                                          */
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // make 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, DECNEG, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberMinus

/* ------------------------------------------------------------------ */
/* decNumberPlus -- prefix plus operator                              */
/*                                                                    */
/*   This computes C = 0 + A                                          */
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // make 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, 0, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberPlus

/* ------------------------------------------------------------------ */
/* decNumberMultiply -- multiply two Numbers                          */
/*                                                                    */
/*   This computes C = A x B                                          */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
                              const decNumber *rhs, decContext *set) {
  uInt status=0;                   // accumulator
  decMultiplyOp(res, lhs, rhs, set, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberMultiply

/* ------------------------------------------------------------------ */
/* decNumberNormalize -- remove trailing zeros                        */
/*                                                                    */
/*   This computes C = 0 + A, and normalizes the result               */
................................................................................
  if (allocdac!=NULL) free(allocdac);   // drop any storage used
  if (allocinv!=NULL) free(allocinv);   // ..
  #if DECSUBSET
  if (alloclhs!=NULL) free(alloclhs);   // ..
  if (allocrhs!=NULL) free(allocrhs);   // ..
  #endif
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberPower

/* ------------------------------------------------------------------ */
/* decNumberQuantize -- force exponent to requested value             */
/*                                                                    */
/*   This computes C = op(A, B), where op adjusts the coefficient     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs,
                               const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberRemainder

/* ------------------------------------------------------------------ */
/* decNumberRemainderNear -- divide and return remainder from nearest */
/*                                                                    */
/*   This computes C = A % B, where % is the IEEE remainder operator  */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs,
                                   const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberRemainderNear

/* ------------------------------------------------------------------ */
/* decNumberSameQuantum -- test for equal exponents                   */
/*                                                                    */
/*   res is the result number, which will contain either 0 or 1       */
................................................................................

    // Here, 0.1 <= a < 1  [Hull]
    a->exponent+=exp/2;                      // set correct exponent

    // Process Subnormals
    decFinalize(a, set, &residue, &status);

    // count dropable zeros [after any subnormal rounding]

    decNumberCopy(b, a);
    decTrim(b, 1, &dropped);                 // [drops trailing zeros]

    // Finally set Inexact and Rounded.  The answer can only be exact if
    // it is short enough so that squaring it could fit in set->digits,
    // so this is the only (relatively rare) time a careful check is
    // needed
................................................................................
        }
       else {                                // plausible
        decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
        if (!ISZERO(t)) {
          status|=DEC_Inexact|DEC_Rounded;
          }
         else {                              // is Exact

          // here, dropped is the count of trailing zeros in 'a'
          // use closest exponent to ideal...
          Int todrop=ideal-a->exponent;      // most that can be dropped

          if (todrop<0) {                    // ideally would add 0s
            status|=DEC_Rounded;
            }
           else {                            // unrounded
            if (dropped<todrop) todrop=dropped; // clamp to those available
            if (todrop>0) {                  // OK, some to drop
              decShiftToLeast(a->lsu, D2U(a->digits), todrop);
................................................................................
              a->exponent+=todrop;           // maintain numerical value
              a->digits-=todrop;             // new length
              }
            }
          }
        }
      }










    decNumberCopy(res, a);                   // assume this is the result
    } while(0);                              // end protected

  if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
  if (allocbufa!=NULL) free(allocbufa);      // ..
  if (allocbufb!=NULL) free(allocbufb);      // ..
  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);       // ..
  #endif
  if (status!=0) decStatus(res, status, set);// then report status



  return res;
  } // decNumberSquareRoot

/* ------------------------------------------------------------------ */
/* decNumberSubtract -- subtract two Numbers                          */
/*                                                                    */
/*   This computes C = A - B                                          */
................................................................................
/* ------------------------------------------------------------------ */
decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs,
                              const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator

  decAddOp(res, lhs, rhs, set, DECNEG, &status);
  if (status!=0) decStatus(res, status, set);



  return res;
  } // decNumberSubtract

/* ------------------------------------------------------------------ */
/* decNumberToIntegralValue -- round-to-integral-value                */
/*                                                                    */
/*   res is the result                                                */
................................................................................
    uInt status=0;
    if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
     else decNaNs(res, rhs, NULL, &status); // a NaN
    if (status!=0) decStatus(res, status, set);
    return res;
    }

  // have a finite number; no error possible
  if (rhs->exponent>=0) return decNumberCopy(res, rhs);
  // that was easy, but if negative exponent there is work to do...
  workset=*set;                    // clone rounding, etc.
  workset.digits=rhs->digits;      // no length rounding
  workset.traps=0;                 // no traps
  decNumberZero(&dn);              // make a number with exponent 0
  return decNumberQuantize(res, rhs, &dn, &workset);
................................................................................
      if (needbytes>(Int)sizeof(zrhibuff)) {
        allocrhi=(uInt *)malloc(needbytes);
        zrhi=allocrhi;}

      // Allocating the accumulator space needs a special case when
      // DECDPUN=1 because when converting the accumulator to Units
      // after the multiplication each 8-byte item becomes 9 1-byte
      // units.  We therefore need iacc extra bytes at the front
      // (rounded up to a multiple of 8 bytes), and the uLong
      // accumulator starts offset the appropriate number of units
      // to the right to avoid overwrite during the unchunking.
      needbytes=iacc*sizeof(uLong);
      #if DECDPUN==1
      zoff=(iacc+7)/8;        // items to offset by
      needbytes+=zoff*8;
................................................................................
    return;
    }

  *status|=DEC_Subnormal;               // have a non-zero subnormal
  adjust=etiny-dn->exponent;            // calculate digits to remove
  if (adjust<=0) {                      // not out of range; unrounded
    // residue can never be non-zero here, except in the Nmin-residue
    // case (which is a subnormal result), so we can fast-path out
    // it may already be inexact (from setting the coefficient)
    if (*status&DEC_Inexact) *status|=DEC_Underflow;
    return;
    }

  // adjust>0, so need to rescale the result so exponent becomes Etiny
  // [this code is similar to that in rescale]
................................................................................
    // if cause was an sNaN, clear and propagate [NaN is already set up]
    if (status & DEC_sNaN) status&=~DEC_sNaN;
     else {
      decNumberZero(dn);                // other error: clean throughout
      dn->bits=DECNAN;                  // and make a quiet NaN
      }
    }
  decContextSetStatus(set, status);
  return;
  } // decStatus

/* ------------------------------------------------------------------ */
/* decGetDigits -- count digits in a Units array                      */
/*                                                                    */
/*   uar is the Unit array holding the number (this is often an       */
................................................................................
/*   dn is the number to check                                        */
/*   set is the context (may be DECUNUSED)                            */
/*   returns 0 if the number is clean, or 1 otherwise                 */
/*                                                                    */
/* The number is considered valid if it could be a result from some   */
/* operation in some valid context (not necessarily the current one). */
/* ------------------------------------------------------------------ */
Flag decCheckNumber(const decNumber *dn, decContext *set) {
  const Unit *up;             // work
  uInt maxuint;               // ..
  Int ae, d, digits;          // ..
  Int emin, emax;             // ..

  if (dn==NULL) {             // hopeless
    #if DECTRACE
................................................................................
    printf("Adjusted exponent overflow [%d].\n", ae);
    decNumberShow(dn);
    #endif
    return 1;}

  return 0;              // it's OK
  } // decCheckNumber






















#endif

#if DECALLOC
#undef malloc
#undef free
/* ------------------------------------------------------------------ */
/* decMalloc -- accountable allocation routine                        */







<
|
>







 







|
|
|


>
>
>




>







 







>







 







|
|
>
>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







|
|







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







>
>
>







 







|
>







 







>


|
<







 







>
>
>
>
>
>
>
>
>
>
|









>
>
>







 







>
>
>







 







|







 







|







 







|







 







|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
...
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
...
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
....
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
....
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
....
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
....
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
....
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
....
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
....
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
....
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
....
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
....
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
....
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021

2022
2023
2024
2025
2026
2027
2028
....
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
....
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
....
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
....
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
....
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
....
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
....
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
....
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
#define COMPMIN   0x03             // ..
#define COMPTOTAL 0x04             // ..
#define COMPNAN   0x05             // .. [NaN processing]

#define DEC_sNaN     0x40000000    // local status: sNaN signal
#define BADINT  (Int)0x80000000    // most-negative Int; error indicator
// Next two indicate an integer >= 10**6, and its parity (bottom bit)

#define BIGEVEN (Int)0x80000002
#define BIGODD  (Int)0x80000003

static Unit uarrone[1]={1};   // Unit array of 1, used for incrementing

/* Granularity-dependent code */
#if DECDPUN<=4
  #define eInt  Int           // extended integer
  #define ueInt uInt          // unsigned extended integer
................................................................................
// To check for memory leaks, the decAllocBytes variable must be
// checked to be 0 at appropriate times (e.g., after the test
// harness completes a set of tests).  This checking may be unreliable
// if the testing is done in a multi-thread environment.
#endif

#if DECCHECK
// Optional checking routines.  Enabling these means that decNumber
// and decContext operands to operator routines are checked for
// correctness.  This roughly doubles the execution time of the
// fastest routines (and adds 600+ bytes), so should not normally be
// used in 'production'.
// decCheckInexact is used to check that inexact results have a full
// complement of digits (where appropriate -- this is not the case
// for Quantize, for example)
#define DECUNUSED (void *)(0xffffffff)
static Flag decCheckOperands(decNumber *, const decNumber *,
                             const decNumber *, decContext *);
static Flag decCheckNumber(const decNumber *, decContext *);
static void decCheckInexact(const decNumber *, decContext *);
#endif

#if DECTRACE || DECCHECK
// Optional trace/debugging routines (may or may not be used)
void decNumberShow(const decNumber *);  // displays the components of a number
static void decDumpAr(char, const Unit *, Int);
#endif
................................................................................
      status=DEC_Conversion_syntax;// assume the worst
      if (*c=='\0') break;         // and no more to come...
      #if DECSUBSET
      // if subset then infinities and NaNs are not allowed
      if (!set->extended) break;   // hopeless
      #endif
      // Infinities and NaNs are possible, here
      if (dotchar!=NULL) break;    // .. unless had a dot
      decNumberZero(dn);           // be optimistic
      if (decBiStr(c, "infinity", "INFINITY")
       || decBiStr(c, "inf", "INF")) {
        dn->bits=bits | DECINF;
        status=0;                  // is OK
        break; // all done
        }
................................................................................
        }
      // something other than 0s; setup last and d as usual [no dots]
      for (c=cfirst;; c++, d++) {
        if (*c<'0' || *c>'9') break; // test for Arabic digit
        last=c;
        }
      if (*c!='\0') break;         // not all digits
      if (d>set->digits-1) {
        // [NB: payload in a decNumber can be full length unless
        // clamped, in which case can only be digits-1]
        if (set->clamp) break;
        if (d>set->digits) break;
        } // too many digits?
      // good; drop through to convert the integer to coefficient
      status=0;                    // syntax is OK
      bits=dn->bits;               // for copy-back
      } // last==NULL

     else if (*c!='\0') {          // more to process...
      // had some digits; exponent is only valid sequence now
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // set 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberAbs

/* ------------------------------------------------------------------ */
/* decNumberAdd -- add two Numbers                                    */
/*                                                                    */
/*   This computes C = A + B                                          */
................................................................................
/* ------------------------------------------------------------------ */
/* This just calls the routine shared with Subtract                   */
decNumber * decNumberAdd(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decAddOp(res, lhs, rhs, set, 0, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberAdd

/* ------------------------------------------------------------------ */
/* decNumberCompare -- compare two Numbers                            */
/*                                                                    */
/*   This computes C = A ? B                                          */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,
                            const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberDivide

/* ------------------------------------------------------------------ */
/* decNumberDivideInteger -- divide and return integer quotient       */
/*                                                                    */
/*   This computes C = A # B, where # is the integer divide operator  */
................................................................................
    } while(0);                         // end protected

  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberExp

/* ------------------------------------------------------------------ */
/* decNumberLn -- natural logarithm                                   */
/*                                                                    */
/*   This computes C = ln(A)                                          */
................................................................................
    } while(0);                         // end protected

  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberLn

/* ------------------------------------------------------------------ */
/* decNumberLog10 -- logarithm in base 10                             */
/*                                                                    */
/*   This computes C = log10(A)                                       */
................................................................................
    aset.digits=p;                      // as calculated
    aset.emax=DEC_MAX_MATH;             // usual bounds
    aset.emin=-DEC_MAX_MATH;            // ..
    aset.clamp=0;                       // and no concrete format
    decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)

    // skip the division if the result so far is infinite, NaN, or
    // zero, or there was an error; note NaN from sNaN needs copy
    if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
    if (a->bits&DECSPECIAL || ISZERO(a)) {
      decNumberCopy(res, a);            // [will fit]
      break;}

    // for ln(10) an extra 3 digits of precision are needed
    p=set->digits+3;
    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
................................................................................
  if (allocbufa!=NULL) free(allocbufa); // drop any storage used
  if (allocbufb!=NULL) free(allocbufb); // ..
  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);  // ..
  #endif
  // apply significant status
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberLog10

/* ------------------------------------------------------------------ */
/* decNumberMax -- compare two Numbers and return the maximum         */
/*                                                                    */
/*   This computes C = A ? B, returning the maximum or A if equal     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberMax

/* ------------------------------------------------------------------ */
/* decNumberMin -- compare two Numbers and return the minimum         */
/*                                                                    */
/*   This computes C = A ? B, returning the minimum or A if equal     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
                         const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberMin

/* ------------------------------------------------------------------ */
/* decNumberMinus -- prefix minus operator                            */
/*                                                                    */
/*   This computes C = 0 - A                                          */
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // make 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, DECNEG, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberMinus

/* ------------------------------------------------------------------ */
/* decNumberPlus -- prefix plus operator                              */
/*                                                                    */
/*   This computes C = 0 + A                                          */
................................................................................
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  #endif

  decNumberZero(&dzero);                // make 0
  dzero.exponent=rhs->exponent;         // [no coefficient expansion]
  decAddOp(res, &dzero, rhs, set, 0, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberPlus

/* ------------------------------------------------------------------ */
/* decNumberMultiply -- multiply two Numbers                          */
/*                                                                    */
/*   This computes C = A x B                                          */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
                              const decNumber *rhs, decContext *set) {
  uInt status=0;                   // accumulator
  decMultiplyOp(res, lhs, rhs, set, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberMultiply

/* ------------------------------------------------------------------ */
/* decNumberNormalize -- remove trailing zeros                        */
/*                                                                    */
/*   This computes C = 0 + A, and normalizes the result               */
................................................................................
  if (allocdac!=NULL) free(allocdac);   // drop any storage used
  if (allocinv!=NULL) free(allocinv);   // ..
  #if DECSUBSET
  if (alloclhs!=NULL) free(alloclhs);   // ..
  if (allocrhs!=NULL) free(allocrhs);   // ..
  #endif
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberPower

/* ------------------------------------------------------------------ */
/* decNumberQuantize -- force exponent to requested value             */
/*                                                                    */
/*   This computes C = op(A, B), where op adjusts the coefficient     */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs,
                               const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberRemainder

/* ------------------------------------------------------------------ */
/* decNumberRemainderNear -- divide and return remainder from nearest */
/*                                                                    */
/*   This computes C = A % B, where % is the IEEE remainder operator  */
................................................................................
/* C must have space for set->digits digits.                          */
/* ------------------------------------------------------------------ */
decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs,
                                   const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator
  decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberRemainderNear

/* ------------------------------------------------------------------ */
/* decNumberSameQuantum -- test for equal exponents                   */
/*                                                                    */
/*   res is the result number, which will contain either 0 or 1       */
................................................................................

    // Here, 0.1 <= a < 1  [Hull]
    a->exponent+=exp/2;                      // set correct exponent

    // Process Subnormals
    decFinalize(a, set, &residue, &status);

    // count droppable zeros [after any subnormal rounding] by
    // trimming a copy
    decNumberCopy(b, a);
    decTrim(b, 1, &dropped);                 // [drops trailing zeros]

    // Finally set Inexact and Rounded.  The answer can only be exact if
    // it is short enough so that squaring it could fit in set->digits,
    // so this is the only (relatively rare) time a careful check is
    // needed
................................................................................
        }
       else {                                // plausible
        decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
        if (!ISZERO(t)) {
          status|=DEC_Inexact|DEC_Rounded;
          }
         else {                              // is Exact
          Int todrop;                        // work
          // here, dropped is the count of trailing zeros in 'a'
          // use closest exponent to ideal...
          todrop=ideal-a->exponent;          // most that can be dropped

          if (todrop<0) {                    // ideally would add 0s
            status|=DEC_Rounded;
            }
           else {                            // unrounded
            if (dropped<todrop) todrop=dropped; // clamp to those available
            if (todrop>0) {                  // OK, some to drop
              decShiftToLeast(a->lsu, D2U(a->digits), todrop);
................................................................................
              a->exponent+=todrop;           // maintain numerical value
              a->digits-=todrop;             // new length
              }
            }
          }
        }
      }

    // make sure there is a full complement of digits for normal
    // inexact results
    if ((status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact) {
      Int shift=set->digits-a->digits;
      if (shift>0) {
        a->digits=decShiftToMost(a->lsu, a->digits, shift);
        a->exponent-=shift;                  // adjust the exponent.
        }
      }
    decNumberCopy(res, a);                   // a is now the result
    } while(0);                              // end protected

  if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
  if (allocbufa!=NULL) free(allocbufa);      // ..
  if (allocbufb!=NULL) free(allocbufb);      // ..
  #if DECSUBSET
  if (allocrhs !=NULL) free(allocrhs);       // ..
  #endif
  if (status!=0) decStatus(res, status, set);// then report status
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberSquareRoot

/* ------------------------------------------------------------------ */
/* decNumberSubtract -- subtract two Numbers                          */
/*                                                                    */
/*   This computes C = A - B                                          */
................................................................................
/* ------------------------------------------------------------------ */
decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs,
                              const decNumber *rhs, decContext *set) {
  uInt status=0;                        // accumulator

  decAddOp(res, lhs, rhs, set, DECNEG, &status);
  if (status!=0) decStatus(res, status, set);
  #if DECCHECK
  decCheckInexact(res, set);
  #endif
  return res;
  } // decNumberSubtract

/* ------------------------------------------------------------------ */
/* decNumberToIntegralValue -- round-to-integral-value                */
/*                                                                    */
/*   res is the result                                                */
................................................................................
    uInt status=0;
    if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
     else decNaNs(res, rhs, NULL, &status); // a NaN
    if (status!=0) decStatus(res, status, set);
    return res;
    }

  // have a finite number; no error possible (res must be big enough)
  if (rhs->exponent>=0) return decNumberCopy(res, rhs);
  // that was easy, but if negative exponent there is work to do...
  workset=*set;                    // clone rounding, etc.
  workset.digits=rhs->digits;      // no length rounding
  workset.traps=0;                 // no traps
  decNumberZero(&dn);              // make a number with exponent 0
  return decNumberQuantize(res, rhs, &dn, &workset);
................................................................................
      if (needbytes>(Int)sizeof(zrhibuff)) {
        allocrhi=(uInt *)malloc(needbytes);
        zrhi=allocrhi;}

      // Allocating the accumulator space needs a special case when
      // DECDPUN=1 because when converting the accumulator to Units
      // after the multiplication each 8-byte item becomes 9 1-byte
      // units.  Therefore iacc extra bytes are needed at the front
      // (rounded up to a multiple of 8 bytes), and the uLong
      // accumulator starts offset the appropriate number of units
      // to the right to avoid overwrite during the unchunking.
      needbytes=iacc*sizeof(uLong);
      #if DECDPUN==1
      zoff=(iacc+7)/8;        // items to offset by
      needbytes+=zoff*8;
................................................................................
    return;
    }

  *status|=DEC_Subnormal;               // have a non-zero subnormal
  adjust=etiny-dn->exponent;            // calculate digits to remove
  if (adjust<=0) {                      // not out of range; unrounded
    // residue can never be non-zero here, except in the Nmin-residue
    // case (which is a subnormal result), so can take fast-path here
    // it may already be inexact (from setting the coefficient)
    if (*status&DEC_Inexact) *status|=DEC_Underflow;
    return;
    }

  // adjust>0, so need to rescale the result so exponent becomes Etiny
  // [this code is similar to that in rescale]
................................................................................
    // if cause was an sNaN, clear and propagate [NaN is already set up]
    if (status & DEC_sNaN) status&=~DEC_sNaN;
     else {
      decNumberZero(dn);                // other error: clean throughout
      dn->bits=DECNAN;                  // and make a quiet NaN
      }
    }
  decContextSetStatus(set, status);     // [may not return]
  return;
  } // decStatus

/* ------------------------------------------------------------------ */
/* decGetDigits -- count digits in a Units array                      */
/*                                                                    */
/*   uar is the Unit array holding the number (this is often an       */
................................................................................
/*   dn is the number to check                                        */
/*   set is the context (may be DECUNUSED)                            */
/*   returns 0 if the number is clean, or 1 otherwise                 */
/*                                                                    */
/* The number is considered valid if it could be a result from some   */
/* operation in some valid context (not necessarily the current one). */
/* ------------------------------------------------------------------ */
static Flag decCheckNumber(const decNumber *dn, decContext *set) {
  const Unit *up;             // work
  uInt maxuint;               // ..
  Int ae, d, digits;          // ..
  Int emin, emax;             // ..

  if (dn==NULL) {             // hopeless
    #if DECTRACE
................................................................................
    printf("Adjusted exponent overflow [%d].\n", ae);
    decNumberShow(dn);
    #endif
    return 1;}

  return 0;              // it's OK
  } // decCheckNumber


/* ------------------------------------------------------------------ */
/* decCheckInexact -- check a normal finite inexact result has digits */
/*   dn is the number to check                                        */
/*   set is the context (for status and precision)                    */
/*   sets Invalid operation, etc., if some digits are missing         */
/* [this check is not made for DECSUBSET compilation]                 */
/* ------------------------------------------------------------------ */
static void decCheckInexact(const decNumber *dn, decContext *set) {
  #if !DECSUBSET
    if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
     && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
      decContextSetStatus(set, DEC_Invalid_operation);
      #if DECTRACE
      printf("Insufficient digits [%d] on normal Inexact result.\n", dn->digits);
      decNumberShow(dn);
      #endif
      }
  #endif
  return;
  } // decCheckInexact
#endif

#if DECALLOC
#undef malloc
#undef free
/* ------------------------------------------------------------------ */
/* decMalloc -- accountable allocation routine                        */

Changes to decNumber/decNumber.h.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
/*   Mike Cowlishaw, IBM Fellow                                       */
/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
/* ------------------------------------------------------------------ */

#if !defined(DECNUMBER)
  #define DECNUMBER
  #define DECNAME     "decNumber"                       /* Short name */
  #define DECVERSION  "decNumber 3.36"           /* Version [16 max.] */
  #define DECFULLNAME "Decimal Number Module"         /* Verbose name */
  #define DECAUTHOR   "Mike Cowlishaw"                /* Who to blame */

  #if !defined(DECCONTEXT)
    #include "decContext.h"
  #endif

................................................................................
    int32_t exponent;              // Unadjusted exponent, unbiased, in
                                   // range: -1999999997 through 999999999
    uint8_t bits;                  // Indicator bits (see above)
    decNumberUnit lsu[DECNUMUNITS];// Coefficient, from least significant unit
    } decNumber;

  // Notes:
  // 1. If digits is > DECDPUN then there will be more than one
  //    decNumberUnits immediately following the first element of lsu.
  //    These contain the remaining (more significant) digits of the
  //    number, and may be in the lsu array, or may be guaranteed by
  //    some other mechanism (such as being contained in another
  //    structure, or being overlaid on dynamically allocated storage).
  //
  //    Each integer of the coefficient (except potentially the last)
  //    contains DECDPUN digits (e.g., a value in the range 0 through
  //    99999999 if DECDPUN is 8, or 0 through 9999 if DECDPUN is 4).
  //
  // 2. A decNumber converted to a string may need up to digits+14
  //    characters.  The worst cases (non-exponential and exponential
  //    formats) are: -0.00000{9...}#
  //             and: -9.{9...}E+999999999#   (where # is '\0')


................................................................................

  // Utilities
  decNumber  * decNumberCopy(decNumber *, const decNumber *);
  decNumber  * decNumberTrim(decNumber *);
  const char * decNumberVersion(void);
  decNumber  * decNumberZero(decNumber *);

  // Macros
  #define decNumberIsZero(dn)     (*(dn)->lsu==0 \
                                   && (dn)->digits==1 \
                                   && (((dn)->bits&DECSPECIAL)==0))
  #define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
  #define decNumberIsNaN(dn)      (((dn)->bits&(DECNAN|DECSNAN))!=0)
  #define decNumberIsQNaN(dn)     (((dn)->bits&(DECNAN))!=0)
  #define decNumberIsSNaN(dn)     (((dn)->bits&(DECSNAN))!=0)
  #define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)


#endif







|







 







|








|







 







|








>


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*   Mike Cowlishaw, IBM Fellow                                       */
/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
/* ------------------------------------------------------------------ */

#if !defined(DECNUMBER)
  #define DECNUMBER
  #define DECNAME     "decNumber"                       /* Short name */
  #define DECVERSION  "decNumber 3.37"           /* Version [16 max.] */
  #define DECFULLNAME "Decimal Number Module"         /* Verbose name */
  #define DECAUTHOR   "Mike Cowlishaw"                /* Who to blame */

  #if !defined(DECCONTEXT)
    #include "decContext.h"
  #endif

................................................................................
    int32_t exponent;              // Unadjusted exponent, unbiased, in
                                   // range: -1999999997 through 999999999
    uint8_t bits;                  // Indicator bits (see above)
    decNumberUnit lsu[DECNUMUNITS];// Coefficient, from least significant unit
    } decNumber;

  // Notes:
  // 1. If digits is > DECDPUN then there will one or more
  //    decNumberUnits immediately following the first element of lsu.
  //    These contain the remaining (more significant) digits of the
  //    number, and may be in the lsu array, or may be guaranteed by
  //    some other mechanism (such as being contained in another
  //    structure, or being overlaid on dynamically allocated storage).
  //
  //    Each integer of the coefficient (except potentially the last)
  //    contains DECDPUN digits (e.g., a value in the range 0 through
  //    99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3).
  //
  // 2. A decNumber converted to a string may need up to digits+14
  //    characters.  The worst cases (non-exponential and exponential
  //    formats) are: -0.00000{9...}#
  //             and: -9.{9...}E+999999999#   (where # is '\0')


................................................................................

  // Utilities
  decNumber  * decNumberCopy(decNumber *, const decNumber *);
  decNumber  * decNumberTrim(decNumber *);
  const char * decNumberVersion(void);
  decNumber  * decNumberZero(decNumber *);

  // Macros for testing decNumbers
  #define decNumberIsZero(dn)     (*(dn)->lsu==0 \
                                   && (dn)->digits==1 \
                                   && (((dn)->bits&DECSPECIAL)==0))
  #define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
  #define decNumberIsNaN(dn)      (((dn)->bits&(DECNAN|DECSNAN))!=0)
  #define decNumberIsQNaN(dn)     (((dn)->bits&(DECNAN))!=0)
  #define decNumberIsSNaN(dn)     (((dn)->bits&(DECSNAN))!=0)
  #define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
  #define decNumberIsSpecial(dn)  (((dn)->bits&DECSPECIAL)!=0)

#endif

Changes to decNumber/decimal128.c.

28
29
30
31
32
33
34
35




36
37
38
39
40
41
42
..
66
67
68
69
70
71
72

73
74
75
76
77
78



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176


177
178
179
180
181
182
183
...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244


245
246
247
248
249
250
251
...
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333


















































































































334




























































335
336
337
338
339
340
341
342

#define  DECNUMDIGITS 34      // make decNumbers with space for 34
#include "decNumber.h"        // base number library
#include "decNumberLocal.h"   // decNumber local types, etc.
#include "decimal128.h"       // our primary include

/* Utility routines and tables [in decimal64.c] */
extern const uInt COMBEXP[32], COMBMSD[32];




extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);

#if DECTRACE || DECCHECK
void decimal128Show(const decimal128 *);          // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
                                  decContext *set) {
  uInt status=0;                   // status accumulator

  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targar[4]={0,0,0,0};        // target 128-bit
  #define targup targar[3]         // name the word with the sign




  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal128]
  if (!(dn->bits&DECSPECIAL)) {              // not a special value
    Int ae=dn->exponent+dn->digits-1;        // adjusted exponent
    if (dn->digits>DECIMAL128_Pmax           // too many digits
     || ae>DECIMAL128_Emax                   // likely overflow
     || ae<DECIMAL128_Emin) {                // likely underflow
      decContextDefault(&dc, DEC_INIT_DECIMAL128); // [no traps]
      dc.round=set->round;                   // use supplied rounding
      decNumberPlus(&dw, dn, &dc);           // (round and check)
      // [this changes -0 to 0, so enforce the sign...]
      dw.bits|=dn->bits&DECNEG;
      status=dc.status;                      // save status
      dn=&dw;                                // use the work number
      }
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targup=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL128_Pmax)) {         // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targup|=DECIMAL_NaN<<24;
       else targup|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL128_Bias) {
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL128_Bias);    // bias exponent
      if (exp>DECIMAL128_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL128_Ehigh;
        exp=DECIMAL128_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }


      decDigitsToDPD(dn, targar, pad);

      // save and clear the top digit
      msd=targup>>14;
      targup&=0x00003fff;

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
             else comb=((exp>>9) & 0x18) | msd;
      }
    targup|=comb<<26;              // add combination field ..
    targup|=(exp&0xfff)<<14;       // .. and exponent continuation
    } // finite

  if (dn->bits&DECNEG) targup|=0x80000000; // add sign bit

  // now write to storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct store, in the right order
  pu=(uInt *)d128->bytes;          // overlay
  if (LITEND) {
    *pu=targar[0];                 // directly store the low int
    pu++;
    *pu=targar[1];                 // then the mid-low
    pu++;
    *pu=targar[2];                 // then the mid-high
    pu++;
    *pu=targar[3];                 // then the high int
    }
   else {
    *pu=targar[3];                 // directly store the high int
    pu++;
    *pu=targar[2];                 // then the mid-high
    pu++;
    *pu=targar[1];                 // then the mid-low
    pu++;
    *pu=targar[0];                 // then the low int


    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    uByte *pb;                     // work
    Int off;                       // ..
    for (pb=&d128->bytes[15]; pb>=d128->bytes; pb--) {
................................................................................
      off=3-((pb-d128->bytes)>>2); // 0, then 1, 2, 3
      *pb=(uByte)(targar[off]&0xff);
      targar[off]>>=8;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d128->bytes;        // overlay
    *pu=targar[3];                 // directly store the high int
    pu++;
    *pu=targar[2];                 // then the mid-high
    pu++;
    *pu=targar[1];                 // then the mid-low
    pu++;
    *pu=targar[0];                 // then the low int
    }
  #endif

  if (status!=0) decContextSetStatus(set, status); // pass on status
  // decimal128Show(d128);
  return d128;
  } // decimal128FromNumber
................................................................................
  #define sourlo sourar[0]         // and the lowest word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d128->bytes;          // overlay
  if (LITEND) {
    sourar[0]=*pu;                 // directly load the low int
    pu++;
    sourar[1]=*pu;                 // then the mid-low
    pu++;
    sourar[2]=*pu;                 // then the mid-high
    pu++;
    sourar[3]=*pu;                 // then the high int
    }
   else {
    sourar[3]=*pu;                 // directly load the high int
    pu++;
    sourar[2]=*pu;                 // then the mid-high
    pu++;
    sourar[1]=*pu;                 // then the mid-low
    pu++;
    sourar[0]=*pu;                 // then the low int


    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d128->bytes; pb<=&d128->bytes[15]; pb++) {
................................................................................
      off=3-((pb-d128->bytes)>>2); // 3, then 2, 1, 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d128->bytes;        // overlay
    sourar[3]=*pu;                 // directly load the high int
    pu++;
    sourar[2]=*pu;                 // then the mid-high
    pu++;
    sourar[1]=*pu;                 // then the mid-low
    pu++;
    sourar[0]=*pu;                 // then the low int
    }
  #endif

  comb=(sourhi>>26)&0x1f;          // combination field

  decNumberZero(dn);               // clean number
  if (sourhi&0x80000000) dn->bits=DECNEG; // set sign if negative
................................................................................
/*  d128 is the decimal128 format number to convert                   */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal128ToString(const decimal128 *d128, char *string){
  decNumber dn;                         // work
  decimal128ToNumber(d128, &dn);
  decNumberToString(&dn, string);
  return string;
  } // decimal128ToString

char * decimal128ToEngString(const decimal128 *d128, char *string){
  decNumber dn;                         // work
  decimal128ToNumber(d128, &dn);
  decNumberToEngString(&dn, string);


















































































































  return string;




























































  } // decimal128ToEngString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal128FromString(result, string, set);                       */
/*                                                                    */
/*  result  is the decimal128 format number which gets the result of  */







|
>
>
>
>







 







>





|
>
>
>






<
|
|
|
|
|
|
|
|
|
|
|
<



|





|
|







 







>

<

|
|





|
|


|






|
|
<
<
|
<
|


|
<
|
<
<
<
<
>
>







 







|
|
|
|
<
<
<







 







|
|
<
<
|
<
|


|
<
|
<
<
<
<
>
>







 







|
|
|
|
<
<
<







 







|


|

|

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
...
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168


169

170
171
172
173

174




175
176
177
178
179
180
181
182
183
...
184
185
186
187
188
189
190
191
192
193
194



195
196
197
198
199
200
201
...
219
220
221
222
223
224
225
226
227


228

229
230
231
232

233




234
235
236
237
238
239
240
241
242
...
243
244
245
246
247
248
249
250
251
252
253



254
255
256
257
258
259
260
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

#define  DECNUMDIGITS 34      // make decNumbers with space for 34
#include "decNumber.h"        // base number library
#include "decNumberLocal.h"   // decNumber local types, etc.
#include "decimal128.h"       // our primary include

/* Utility routines and tables [in decimal64.c] */
extern const uInt   COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];      // [not used]
extern const uByte  BIN2CHAR[4001];

extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);

#if DECTRACE || DECCHECK
void decimal128Show(const decimal128 *);          // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
                                  decContext *set) {
  uInt status=0;                   // status accumulator
  Int ae;                          // adjusted exponent
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targar[4]={0,0,0,0};        // target 128-bit
  #define targhi targar[3]         // name the word with the sign
  #define targmh targar[2]         // name the words
  #define targml targar[1]         // ..
  #define targlo targar[0]         // ..

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal128]

  ae=dn->exponent+dn->digits-1;              // [0 if special]
  if (dn->digits>DECIMAL128_Pmax             // too many digits
   || ae>DECIMAL128_Emax                     // likely overflow
   || ae<DECIMAL128_Emin) {                  // likely underflow
    decContextDefault(&dc, DEC_INIT_DECIMAL128); // [no traps]
    dc.round=set->round;                     // use supplied rounding
    decNumberPlus(&dw, dn, &dc);             // (round and check)
    // [this changes -0 to 0, so enforce the sign...]
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;                        // save status
    dn=&dw;                                  // use the work number

    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL128_Pmax)) {         // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
       else targhi|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL128_Bias) {
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL128_Bias);    // bias exponent
      if (exp>DECIMAL128_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL128_Ehigh;
        exp=DECIMAL128_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      // [fastpath for common case is not a win, here]
      decDigitsToDPD(dn, targar, pad);

      // save and clear the top digit
      msd=targhi>>14;
      targhi&=0x00003fff;

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
             else comb=((exp>>9) & 0x18) | msd;
      }
    targhi|=comb<<26;              // add combination field ..
    targhi|=(exp&0xfff)<<14;       // .. and exponent continuation
    } // finite

  if (dn->bits&DECNEG) targhi|=0x80000000; // add sign bit

  // now write to storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct store, in the right order
  pu=(uInt *)d128->bytes;          // overlay
  if (LITEND) {
    pu[0]=targlo;                  // directly store the low int
    pu[1]=targml;                  // then the mid-low


    pu[2]=targmh;                  // then the mid-high

    pu[3]=targhi;                  // then the high int
    }
   else {
    pu[0]=targhi;                  // directly store the high int

    pu[1]=targmh;                  // then the mid-high




    pu[2]=targml;                  // then the mid-low
    pu[3]=targlo;                  // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    uByte *pb;                     // work
    Int off;                       // ..
    for (pb=&d128->bytes[15]; pb>=d128->bytes; pb--) {
................................................................................
      off=3-((pb-d128->bytes)>>2); // 0, then 1, 2, 3
      *pb=(uByte)(targar[off]&0xff);
      targar[off]>>=8;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d128->bytes;        // overlay
    pu[0]=targhi;                  // directly store the high int
    pu[1]=targmh;                  // then the mid-high
    pu[2]=targml;                  // then the mid-low
    pu[3]=targlo;                  // then the low int



    }
  #endif

  if (status!=0) decContextSetStatus(set, status); // pass on status
  // decimal128Show(d128);
  return d128;
  } // decimal128FromNumber
................................................................................
  #define sourlo sourar[0]         // and the lowest word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d128->bytes;          // overlay
  if (LITEND) {
    sourlo=pu[0];                  // directly load the low int
    sourml=pu[1];                  // then the mid-low


    sourmh=pu[2];                  // then the mid-high

    sourhi=pu[3];                  // then the high int
    }
   else {
    sourhi=pu[0];                  // directly load the high int

    sourmh=pu[1];                  // then the mid-high




    sourml=pu[2];                  // then the mid-low
    sourlo=pu[3];                  // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d128->bytes; pb<=&d128->bytes[15]; pb++) {
................................................................................
      off=3-((pb-d128->bytes)>>2); // 3, then 2, 1, 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d128->bytes;        // overlay
    sourhi=pu[0];                  // directly load the high int
    sourmh=pu[1];                  // then the mid-high
    sourml=pu[2];                  // then the mid-low
    sourlo=pu[3];                  // then the low int



    }
  #endif

  comb=(sourhi>>26)&0x1f;          // combination field

  decNumberZero(dn);               // clean number
  if (sourhi&0x80000000) dn->bits=DECNEG; // set sign if negative
................................................................................
/*  d128 is the decimal128 format number to convert                   */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal128ToEngString(const decimal128 *d128, char *string){
  decNumber dn;                         // work
  decimal128ToNumber(d128, &dn);
  decNumberToEngString(&dn, string);
  return string;
  } // decimal128ToEngString

char * decimal128ToString(const decimal128 *d128, char *string){
  uInt msd;                        // coefficient MSD
  Int  exp;                        // exponent top two bits or full
  uInt comb;                       // combination field
  char *cstart;                    // coefficient start
  char *c;                         // output pointer in string
  uInt *pu;                        // work
  char *s, *t;                     // .. (source, target)
  Int  dpd;                        // ..
  Int  pre, e;                     // ..
  const uByte *u;                  // ..

  uInt sourar[4];                  // source 128-bit
  #define sourhi sourar[3]         // name the word with the sign
  #define sourmh sourar[2]         // and the mid-high word
  #define sourml sourar[1]         // and the mod-low word
  #define sourlo sourar[0]         // and the lowest word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d128->bytes;          // overlay
  if (LITEND) {
    sourlo=pu[0];                  // directly load the low int
    sourml=pu[1];                  // then the mid-low
    sourmh=pu[2];                  // then the mid-high
    sourhi=pu[3];                  // then the high int
    }
   else {
    sourhi=pu[0];                  // directly load the high int
    sourmh=pu[1];                  // then the mid-high
    sourml=pu[2];                  // then the mid-low
    sourlo=pu[3];                  // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d128->bytes; pb<=&d128->bytes[15]; pb++) {
      off=3-((pb-d128->bytes)>>2); // 3, then 2, 1, 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d128->bytes;        // overlay
    sourhi=pu[0];                  // directly load the high int
    sourmh=pu[1];                  // then the mid-high
    sourml=pu[2];                  // then the mid-low
    sourlo=pu[3];                  // then the low int
    }
  #endif

  c=string;                        // where result will go
  if (((Int)sourhi)<0) *c++='-';   // handle sign

  comb=(sourhi>>26)&0x1f;          // combination field
  msd=COMBMSD[comb];               // decode the combination field
  exp=COMBEXP[comb];               // ..

  if (exp==3) {
    if (msd==0) {                  // infinity
      strcpy(c, "Infinity");
      return string;               // easy
      }
    if (sourhi&0x02000000) *c++='s'; // sNaN
    strcpy(c, "NaN");              // complete word
    c+=3;                          // step past
    if (sourlo==0 && sourml==0 && sourmh==0
     && (sourhi&0x0003ffff)==0) return string; // zero payload
    // otherwise drop through to add integer; set correct exp
    exp=0; msd=0;                  // setup for following code
    }
   else exp=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; // unbiased

  // convert 34 digits of significand to characters
  cstart=c;                        // save start of coefficient
  if (msd) *c++='0'+(char)msd;     // non-zero most significant digit

  // Now decode the declets.  After extracting each one, it is
  // decoded to binary and then to a 4-char sequence by table lookup;
  // the 4-chars are a 1-char length (significant digits, except 000
  // has length 0).  This allows us to left-align the first declet
  // with non-zero content, then remaining ones are full 3-char
  // length.  We use fixed-length memcpys because variable-length
  // causes a subroutine call in GCC.  (These are length 4 for speed
  // and are safe because the array has an extra terminator byte.)
  #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];                   \
                   if (c!=cstart) {memcpy(c, u+1, 4); c+=3;}      \
                    else if (*u)  {memcpy(c, u+4-*u, 4); c+=*u;}
  dpd=(sourhi>>4)&0x3ff;                     // declet 1
  dpd2char;
  dpd=((sourhi&0xf)<<6) | (sourmh>>26);      // declet 2
  dpd2char;
  dpd=(sourmh>>16)&0x3ff;                    // declet 3
  dpd2char;
  dpd=(sourmh>>6)&0x3ff;                     // declet 4
  dpd2char;
  dpd=((sourmh&0x3f)<<4) | (sourml>>28);     // declet 5
  dpd2char;
  dpd=(sourml>>18)&0x3ff;                    // declet 6
  dpd2char;
  dpd=(sourml>>8)&0x3ff;                     // declet 7
  dpd2char;
  dpd=((sourml&0xff)<<2) | (sourlo>>30);     // declet 8
  dpd2char;
  dpd=(sourlo>>20)&0x3ff;                    // declet 9
  dpd2char;
  dpd=(sourlo>>10)&0x3ff;                    // declet 10
  dpd2char;
  dpd=(sourlo)&0x3ff;                        // declet 11
  dpd2char;

  if (c==cstart) *c++='0';         // all zeros -- make 0

  if (exp==0) {                    // integer or NaN case -- easy
    *c='\0';                       // terminate
    return string;
    }

  /* non-0 exponent */
  e=0;                             // assume no E
  pre=c-cstart+exp;
  // [here, pre-exp is the digits count (==1 for zero)]
  if (exp>0 || pre<-5) {           // need exponential form
    e=pre-1;                       // calculate E value
    pre=1;                         // assume one digit before '.'
    } // exponential form

  /* modify the coefficient, adding 0s, '.', and E+nn as needed */
  s=c-1;                           // source (LSD)
  if (pre>0) {                     // ddd.ddd (plain), perhaps with E
    char *dotat=cstart+pre;
    if (dotat<c) {                 // if embedded dot needed...
      t=c;                              // target
      for (; s>=dotat; s--, t--) *t=*s; // open the gap; leave t at gap
      *t='.';                           // insert the dot
      c++;                              // length increased by one
      }

    // finally add the E-part, if needed; it will never be 0, and has
    // a maximum length of 4 digits
    if (e!=0) {
      *c++='E';                    // starts with E
      *c++='+';                    // assume positive
      if (e<0) {
        *(c-1)='-';                // oops, need '-'
        e=-e;                      // uInt, please
        }
      if (e<1000) {                // 3 (or fewer) digits case
        u=&BIN2CHAR[e*4];          // -> length byte
        memcpy(c, u+4-*u, 4);      // copy fixed 4 characters [is safe]
        c+=*u;                     // bump pointer appropriately
        }
       else {                      // 4-digits
        Int thou=((e>>3)*1049)>>17; // e/1000
        Int rem=e-(1000*thou);      // e%1000
        *c++='0'+(char)thou;
        u=&BIN2CHAR[rem*4];        // -> length byte
        memcpy(c, u+1, 4);         // copy fixed 3+1 characters [is safe]
        c+=3;                      // bump pointer, always 3 digits
        }
      }
    *c='\0';                       // add terminator
    //printf("res %s\n", string);
    return string;
    } // pre>0

  /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
  t=c+1-pre;
  *(t+1)='\0';                          // can add terminator now
  for (; s>=cstart; s--, t--) *t=*s;    // shift whole coefficient right
  c=cstart;
  *c++='0';                             // always starts with 0.
  *c++='.';
  for (; pre<0; pre++) *c++='0';        // add any 0's after '.'
  //printf("res %s\n", string);
  return string;
  } // decimal128ToString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal128FromString(result, string, set);                       */
/*                                                                    */
/*  result  is the decimal128 format number which gets the result of  */

Changes to decNumber/decimal32.c.

28
29
30
31
32
33
34
35




36
37
38
39
40
41
42
..
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
134
135
136
137
138
139
140
141




142


143
144
145

146
147
148
149
150
151
152
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277












































































278


















































279
280
281
282
283
284
285
286

#define  DECNUMDIGITS  7      // make decNumbers with space for 7
#include "decNumber.h"        // base number library
#include "decNumberLocal.h"   // decNumber local types, etc.
#include "decimal32.h"        // our primary include

/* Utility tables and routines [in decimal64.c] */
extern const uInt COMBEXP[32], COMBMSD[32];




extern void decDigitsToDPD(const decNumber *, uInt *, Int);
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);

#if DECTRACE || DECCHECK
void decimal32Show(const decimal32 *);            // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
                              decContext *set) {
  uInt status=0;                   // status accumulator

  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targ=0;                     // target 32-bit

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal32]
  if (!(dn->bits&DECSPECIAL)) {              // not a special value
    Int ae=dn->exponent+dn->digits-1;        // adjusted exponent
    if (dn->digits>DECIMAL32_Pmax            // too many digits
     || ae>DECIMAL32_Emax                    // likely overflow
     || ae<DECIMAL32_Emin) {                 // likely underflow
      decContextDefault(&dc, DEC_INIT_DECIMAL32); // [no traps]
      dc.round=set->round;                   // use supplied rounding
      decNumberPlus(&dw, dn, &dc);           // (round and check)
      // [this changes -0 to 0, so enforce the sign...]
      dw.bits|=dn->bits&DECNEG;
      status=dc.status;                      // save status
      dn=&dw;                                // use the work number
      }
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL32_Pmax)) {          // coefficient fits
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL32_Bias);    // bias exponent
      if (exp>DECIMAL32_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL32_Ehigh;
        exp=DECIMAL32_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      decDigitsToDPD(dn, &targ, pad);







      // save and clear the top digit
      msd=targ>>20;
      targ&=0x000fffff;


      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
             else comb=((exp>>3) & 0x18) | msd;
      }
    targ|=comb<<26;                // add combination field ..
    targ|=(exp&0x3f)<<20;          // .. and exponent continuation
................................................................................
/*  d32 is the decimal32 format number to convert                     */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal32ToString(const decimal32 *d32, char *string){
  decNumber dn;                         // work
  decimal32ToNumber(d32, &dn);
  decNumberToString(&dn, string);
  return string;
  } // decimal32ToString

char * decimal32ToEngString(const decimal32 *d32, char *string){
  decNumber dn;                         // work
  decimal32ToNumber(d32, &dn);
  decNumberToEngString(&dn, string);












































































  return string;


















































  } // decimal32ToEngString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal32FromString(result, string, set);                        */
/*                                                                    */
/*  result  is the decimal32 format number which gets the result of   */







|
>
>
>
>







 







>











<
|
|
|
|
|
|
|
|
|
|
|
<







 







|
>
>
>
>
|
>
>
|
|
|
>







 







|


|

|

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

#define  DECNUMDIGITS  7      // make decNumbers with space for 7
#include "decNumber.h"        // base number library
#include "decNumberLocal.h"   // decNumber local types, etc.
#include "decimal32.h"        // our primary include

/* Utility tables and routines [in decimal64.c] */
extern const uInt   COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];
extern const uByte  BIN2CHAR[4001];

extern void decDigitsToDPD(const decNumber *, uInt *, Int);
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);

#if DECTRACE || DECCHECK
void decimal32Show(const decimal32 *);            // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
                              decContext *set) {
  uInt status=0;                   // status accumulator
  Int ae;                          // adjusted exponent
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targ=0;                     // target 32-bit

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal32]

  ae=dn->exponent+dn->digits-1;              // [0 if special]
  if (dn->digits>DECIMAL32_Pmax              // too many digits
   || ae>DECIMAL32_Emax                      // likely overflow
   || ae<DECIMAL32_Emin) {                   // likely underflow
    decContextDefault(&dc, DEC_INIT_DECIMAL32); // [no traps]
    dc.round=set->round;                     // use supplied rounding
    decNumberPlus(&dw, dn, &dc);             // (round and check)
    // [this changes -0 to 0, so enforce the sign...]
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;                        // save status
    dn=&dw;                                  // use the work number

    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL32_Pmax)) {          // coefficient fits
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL32_Bias);    // bias exponent
      if (exp>DECIMAL32_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL32_Ehigh;
        exp=DECIMAL32_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      // fastpath common case
      if (DECDPUN==3 && pad==0) {
        targ=BIN2DPD[dn->lsu[0]];
        if (dn->digits>3) targ|=(uInt)(BIN2DPD[dn->lsu[1]])<<10;
        msd=(dn->digits==7 ? dn->lsu[2] : 0);
        }
       else { // general case
        decDigitsToDPD(dn, &targ, pad);
        // save and clear the top digit
        msd=targ>>20;
        targ&=0x000fffff;
        }

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
             else comb=((exp>>3) & 0x18) | msd;
      }
    targ|=comb<<26;                // add combination field ..
    targ|=(exp&0x3f)<<20;          // .. and exponent continuation
................................................................................
/*  d32 is the decimal32 format number to convert                     */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal32ToEngString(const decimal32 *d32, char *string){
  decNumber dn;                         // work
  decimal32ToNumber(d32, &dn);
  decNumberToEngString(&dn, string);
  return string;
  } // decimal32ToEngString

char * decimal32ToString(const decimal32 *d32, char *string){
  uInt msd;                        // coefficient MSD
  Int  exp;                        // exponent top two bits or full
  uInt comb;                       // combination field
  char *cstart;                    // coefficient start
  char *c;                         // output pointer in string
  uInt *pu;                        // work
  char *s, *t;                     // .. (source, target)
  Int  dpd;                        // ..
  Int  pre, e;                     // ..
  const uByte *u;                  // ..
  uInt sour;                       // source 32-bit

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load
  pu=(uInt *)d32->bytes;           // overlay
  sour=*pu;                        // directly load the int
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    sour=0;                        // [keep compiler quiet]
    for (pb=d32->bytes; pb<=&d32->bytes[3]; pb++) {
      sour<<=8;
      sour|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d32->bytes;         // overlay
    sour=*pu;                      // directly load the int
    }
  #endif

  c=string;                        // where result will go
  if (((Int)sour)<0) *c++='-';     // handle sign

  comb=(sour>>26)&0x1f;            // combination field
  msd=COMBMSD[comb];               // decode the combination field
  exp=COMBEXP[comb];               // ..

  if (exp==3) {
    if (msd==0) {                  // infinity
      strcpy(c, "Infinity");
      return string;               // easy
      }
    if (sour&0x02000000) *c++='s'; // sNaN
    strcpy(c, "NaN");              // complete word
    c+=3;                          // step past
    if ((sour&0x000fffff)==0) return string; // zero payload
    // otherwise drop through to add integer; set correct exp
    exp=0; msd=0;                  // setup for following code
    }
   else exp=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; // unbiased

  // convert 7 digits of significand to characters
  cstart=c;                        // save start of coefficient
  if (msd) *c++='0'+(char)msd;     // non-zero most significant digit

  // Now decode the declets.  After extracting each one, it is
  // decoded to binary and then to a 4-char sequence by table lookup;
  // the 4-chars are a 1-char length (significant digits, except 000
  // has length 0).  This allows us to left-align the first declet
  // with non-zero content, then remaining ones are full 3-char
  // length.  We use fixed-length memcpys because variable-length
  // causes a subroutine call in GCC.  (These are length 4 for speed
  // and are safe because the array has an extra terminator byte.)
  #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];                   \
                   if (c!=cstart) {memcpy(c, u+1, 4); c+=3;}      \
                    else if (*u)  {memcpy(c, u+4-*u, 4); c+=*u;}

  dpd=(sour>>10)&0x3ff;            // declet 1
  dpd2char;
  dpd=(sour)&0x3ff;                // declet 2
  dpd2char;

  if (c==cstart) *c++='0';         // all zeros -- make 0

  if (exp==0) {                    // integer or NaN case -- easy
    *c='\0';                       // terminate
    return string;
    }

  /* non-0 exponent */
  e=0;                             // assume no E
  pre=c-cstart+exp;
  // [here, pre-exp is the digits count (==1 for zero)]
  if (exp>0 || pre<-5) {           // need exponential form
    e=pre-1;                       // calculate E value
    pre=1;                         // assume one digit before '.'
    } // exponential form

  /* modify the coefficient, adding 0s, '.', and E+nn as needed */
  s=c-1;                           // source (LSD)
  if (pre>0) {                     // ddd.ddd (plain), perhaps with E
    char *dotat=cstart+pre;
    if (dotat<c) {                 // if embedded dot needed...
      t=c;                              // target
      for (; s>=dotat; s--, t--) *t=*s; // open the gap; leave t at gap
      *t='.';                           // insert the dot
      c++;                              // length increased by one
      }

    // finally add the E-part, if needed; it will never be 0, and has
    // a maximum length of 3 digits (E-101 case)
    if (e!=0) {
      *c++='E';                    // starts with E
      *c++='+';                    // assume positive
      if (e<0) {
        *(c-1)='-';                // oops, need '-'
        e=-e;                      // uInt, please
        }
      u=&BIN2CHAR[e*4];            // -> length byte
      memcpy(c, u+4-*u, 4);        // copy fixed 4 characters [is safe]
      c+=*u;                       // bump pointer appropriately
      }
    *c='\0';                       // add terminator
    //printf("res %s\n", string);
    return string;
    } // pre>0

  /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
  t=c+1-pre;
  *(t+1)='\0';                          // can add terminator now
  for (; s>=cstart; s--, t--) *t=*s;    // shift whole coefficient right
  c=cstart;
  *c++='0';                             // always starts with 0.
  *c++='.';
  for (; pre<0; pre++) *c++='0';        // add any 0's after '.'
  //printf("res %s\n", string);
  return string;
  } // decimal32ToString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal32FromString(result, string, set);                        */
/*                                                                    */
/*  result  is the decimal32 format number which gets the result of   */

Changes to decNumber/decimal64.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51






52
53
54
55
56
57
58
..
66
67
68
69
70
71
72

73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
133
134
135
136
137
138
139
140












141




142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311






























































































312


















































313
314
315
316
317
318
319
320
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
...
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
extern void decDigitsToDPD(const decNumber *, uInt *, Int);

#if DECTRACE || DECCHECK
void decimal64Show(const decimal64 *);            // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif

/* compile-time endian tester [assumes sizeof(int)>1] */
static  const  Int mfcone=1;                 // constant 1
static  const  Flag *mfctop=(Flag *)&mfcone; // -> top byte
#define LITEND mfctop[0]           // named flag; 1=little-endian

/* Useful macro */
// Clear a structure (e.g., a decNumber)
#define DEC_clear(d) memset(d, 0, sizeof(*d))







/* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64              */
/*                                                                    */
/*   ds is the target decimal64                                       */
/*   dn is the source number (assumed valid)                          */
/*   set is the context, used only for reporting errors               */
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
                                decContext *set) {
  uInt status=0;                   // status accumulator

  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targar[2]={0,0};            // target 64-bit
  #define targup targar[1]         // name the word with the sign


  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal64]
  if (!(dn->bits&DECSPECIAL)) {              // not a special value
    Int ae=dn->exponent+dn->digits-1;        // adjusted exponent
    if (dn->digits>DECIMAL64_Pmax            // too many digits
     || ae>DECIMAL64_Emax                    // likely overflow
     || ae<DECIMAL64_Emin) {                 // likely underflow
      decContextDefault(&dc, DEC_INIT_DECIMAL64); // [no traps]
      dc.round=set->round;                   // use supplied rounding
      decNumberPlus(&dw, dn, &dc);           // (round and check)
      // [this changes -0 to 0, so enforce the sign...]
      dw.bits|=dn->bits&DECNEG;
      status=dc.status;                      // save status
      dn=&dw;                                // use the work number
      }
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targup=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL64_Pmax)) {          // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targup|=DECIMAL_NaN<<24;
       else targup|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL64_Bias) {
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL64_Bias);    // bias exponent
      if (exp>DECIMAL64_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL64_Ehigh;
        exp=DECIMAL64_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      decDigitsToDPD(dn, targar, pad);

















      // save and clear the top digit
      msd=targup>>18;
      targup&=0x0003ffff;


      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01);
             else comb=((exp>>5) & 0x18) | msd;
      }
    targup|=comb<<26;              // add combination field ..
    targup|=(exp&0xff)<<18;        // .. and exponent continuation
    } // finite

  if (dn->bits&DECNEG) targup|=0x80000000; // add sign bit

  // now write to storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct store, in the right order
  pu=(uInt *)d64->bytes;           // overlay
  if (LITEND) {
    *pu=targar[0];                 // directly store the low int
    pu++;
    *pu=targar[1];                 // then the high int
    }
   else {
    *pu=targar[1];                 // directly store the high int
    pu++;
    *pu=targar[0];                 // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    uByte *pb;                     // work
    Int off;                       // ..
    for (pb=&d64->bytes[7]; pb>=d64->bytes; pb--) {
................................................................................
      off=1-((pb-d64->bytes)>>2);  // 0 then 1
      *pb=(uByte)(targar[off]&0xff);
      targar[off]>>=8;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d64->bytes;         // overlay
    *pu=targar[1];                 // directly store the high int
    pu++;
    *pu=targar[0];                 // then the low int
    }
  #endif

  if (status!=0) decContextSetStatus(set, status); // pass on status
  // decimal64Show(d64);
  return d64;
  } // decimal64FromNumber
................................................................................
  #define sourlo sourar[0]         // and the lower word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d64->bytes;           // overlay
  if (LITEND) {
    sourar[0]=*pu;                 // directly load the low int
    pu++;
    sourar[1]=*pu;                 // then the high int
    }
   else {
    sourar[1]=*pu;                 // directly load the high int
    pu++;
    sourar[0]=*pu;                 // then the low int

    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d64->bytes; pb<=&d64->bytes[7]; pb++) {
................................................................................
      off=1-((pb-d64->bytes)>>2);  // 1 then 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d64->bytes;         // overlay
    sourar[1]=*pu;                 // directly load the high int
    pu++;
    sourar[0]=*pu;                 // then the low int
    }
  #endif

  comb=(sourhi>>26)&0x1f;          // combination field

  decNumberZero(dn);               // clean number
  if (sourhi&0x80000000) dn->bits=DECNEG; // set sign if negative
................................................................................
  // get the coefficient
  sourhi&=0x0003ffff;              // clean coefficient continuation
  if (msd) {                       // non-zero msd
    sourhi|=msd<<18;               // prefix to coefficient
    need=6;                        // process 6 declets
    }
   else { // msd=0
    if (!sourhi) {                   // top word 0
      if (!sourlo) return dn;        // easy: coefficient is 0
      need=3;                        // process at least 3 declets
      if (sourlo&0xc0000000) need++; // process 4 declets
      // [could reduce some more, here]
      }
     else {                          // some bits in top word, msd=0
      need=4;                        // process at least 4 declets
      if (sourhi&0x0003ff00) need++; // top declet!=0, process 5
      }
    } //msd=0

  decDigitsFromDPD(dn, sourar, need);   // process declets
  return dn;
  } // decimal64ToNumber


/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string               */
/* to-engineering-string -- conversion to numeric string              */
/*                                                                    */
/*   decimal64ToString(d64, string);                                  */
/*   decimal64ToEngString(d64, string);                               */
................................................................................
/*  d64 is the decimal64 format number to convert                     */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal64ToString(const decimal64 *d64, char *string){
  decNumber dn;                         // work
  decimal64ToNumber(d64, &dn);
  decNumberToString(&dn, string);
  return string;
  } // decimal64ToString

char * decimal64ToEngString(const decimal64 *d64, char *string){
  decNumber dn;                         // work
  decimal64ToNumber(d64, &dn);
  decNumberToEngString(&dn, string);






























































































  return string;


















































  } // decimal64ToEngString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal64FromString(result, string, set);                        */
/*                                                                    */
/*  result  is the decimal64 format number which gets the result of   */
................................................................................
  #endif
  } // decimal64Show
#endif

/* ================================================================== */
/* Shared utility routines and tables                                 */
/* ================================================================== */

// define and include the conversion tables to use
#define DEC_BIN2DPD 1         // used for all sizes
#if DECDPUN==3
  #define DEC_DPD2BIN 1
#else
  #define DEC_DPD2BCD 1
#endif
#include "decDPD.h"           // lookup tables

................................................................................
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work)    */
/*                                                                    */
/*      COMBEXP - 2-bit most-significant-bits of exponent             */
/*                [11 if an Infinity or NaN]                          */
/*      COMBMSD - 4-bit most-significant-digit                        */
/*                [0=Infinity, 1=NaN if COMBEXP=11]                   */
/* Both indexed by the combination field (5 bits)                     */

/* ------------------------------------------------------------------ */
const uInt COMBEXP[32]={0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
                        2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 3, 3};
const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
                        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1};

/* ------------------------------------------------------------------ */







|


|




>
>
>
>
>
>







 







>




|
|
>






<
|
|
|
|
|
|
|
|
|
|
|
<



|





|
|







 







|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
|
>





|
|


|






|
<
|


|
<
|







 







|
<
|







 







|
<
|


|
<
<
>







 







|
|
<







 







|
|
|



|
|







>







 







|


|

|

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







<
|
<







 







|
>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188

189
190
191
192
193
194
195
196
...
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
...
228
229
230
231
232
233
234
235

236
237
238
239


240
241
242
243
244
245
246
247
...
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
537
538
539
540
541
542
543

544

545
546
547
548
549
550
551
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
extern void decDigitsToDPD(const decNumber *, uInt *, Int);

#if DECTRACE || DECCHECK
void decimal64Show(const decimal64 *);            // for debug
extern void decNumberShow(const decNumber *);     // ..
#endif

/* compile-time endian tester [assumes sizeof(Int)>1] */
static  const  Int mfcone=1;                 // constant 1
static  const  Flag *mfctop=(Flag *)&mfcone; // -> top byte
#define LITEND *mfctop             // named flag; 1=little-endian

/* Useful macro */
// Clear a structure (e.g., a decNumber)
#define DEC_clear(d) memset(d, 0, sizeof(*d))

/* define and include the tables to use for conversions */
#define DEC_BIN2CHAR 1
#define DEC_DPD2BIN  1
#define DEC_BIN2DPD  1             // used for all sizes
#include "decDPD.h"                // lookup tables

/* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64              */
/*                                                                    */
/*   ds is the target decimal64                                       */
/*   dn is the source number (assumed valid)                          */
/*   set is the context, used only for reporting errors               */
................................................................................
/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
/* by reducing its exponent and multiplying the coefficient by a      */
/* power of ten, or if the exponent on a zero had to be clamped.      */
/* ------------------------------------------------------------------ */
decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
                                decContext *set) {
  uInt status=0;                   // status accumulator
  Int ae;                          // adjusted exponent
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targar[2]={0, 0};           // target 64-bit
  #define targhi targar[1]         // name the word with the sign
  #define targlo targar[0]         // and the other

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal64]

  ae=dn->exponent+dn->digits-1;              // [0 if special]
  if (dn->digits>DECIMAL64_Pmax              // too many digits
   || ae>DECIMAL64_Emax                      // likely overflow
   || ae<DECIMAL64_Emin) {                   // likely underflow
    decContextDefault(&dc, DEC_INIT_DECIMAL64); // [no traps]
    dc.round=set->round;                     // use supplied rounding
    decNumberPlus(&dw, dn, &dc);             // (round and check)
    // [this changes -0 to 0, so enforce the sign...]
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;                        // save status
    dn=&dw;                                  // use the work number

    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL64_Pmax)) {          // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
       else targhi|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL64_Bias) {
................................................................................
      exp=(uInt)(dn->exponent+DECIMAL64_Bias);    // bias exponent
      if (exp>DECIMAL64_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL64_Ehigh;
        exp=DECIMAL64_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      // fastpath common case
      if (DECDPUN==3 && pad==0) {
        uInt dpd[6]={0,0,0,0,0,0};
        uInt i;
        Int d=dn->digits;
        for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]];
        targlo =dpd[0];
        targlo|=dpd[1]<<10;
        targlo|=dpd[2]<<20;
        if (dn->digits>6) {
          targlo|=dpd[3]<<30;
          targhi =dpd[3]>>2;
          targhi|=dpd[4]<<8;
          }
        msd=dpd[5];                // [did not really need conversion]
        }
       else { // general case
        decDigitsToDPD(dn, targar, pad);
        // save and clear the top digit
        msd=targhi>>18;
        targhi&=0x0003ffff;
        }

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01);
             else comb=((exp>>5) & 0x18) | msd;
      }
    targhi|=comb<<26;              // add combination field ..
    targhi|=(exp&0xff)<<18;        // .. and exponent continuation
    } // finite

  if (dn->bits&DECNEG) targhi|=0x80000000; // add sign bit

  // now write to storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct store, in the right order
  pu=(uInt *)d64->bytes;           // overlay
  if (LITEND) {
    pu[0]=targar[0];               // directly store the low int

    pu[1]=targar[1];               // then the high int
    }
   else {
    pu[0]=targar[1];               // directly store the high int

    pu[1]=targar[0];               // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    uByte *pb;                     // work
    Int off;                       // ..
    for (pb=&d64->bytes[7]; pb>=d64->bytes; pb--) {
................................................................................
      off=1-((pb-d64->bytes)>>2);  // 0 then 1
      *pb=(uByte)(targar[off]&0xff);
      targar[off]>>=8;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d64->bytes;         // overlay
    pu[0]=targar[1];               // directly store the high int

    pu[1]=targar[0];               // then the low int
    }
  #endif

  if (status!=0) decContextSetStatus(set, status); // pass on status
  // decimal64Show(d64);
  return d64;
  } // decimal64FromNumber
................................................................................
  #define sourlo sourar[0]         // and the lower word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d64->bytes;           // overlay
  if (LITEND) {
    sourlo=pu[0];                  // directly load the low int

    sourhi=pu[1];                  // then the high int
    }
   else {
    sourhi=pu[0];                  // directly load the high int


    sourlo=pu[1];                  // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d64->bytes; pb<=&d64->bytes[7]; pb++) {
................................................................................
      off=1-((pb-d64->bytes)>>2);  // 1 then 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d64->bytes;         // overlay
    sourhi=pu[0];                  // directly load the high int
    sourlo=pu[1];                  // then the low int

    }
  #endif

  comb=(sourhi>>26)&0x1f;          // combination field

  decNumberZero(dn);               // clean number
  if (sourhi&0x80000000) dn->bits=DECNEG; // set sign if negative
................................................................................
  // get the coefficient
  sourhi&=0x0003ffff;              // clean coefficient continuation
  if (msd) {                       // non-zero msd
    sourhi|=msd<<18;               // prefix to coefficient
    need=6;                        // process 6 declets
    }
   else { // msd=0
    if (!sourhi) {                 // top word 0
      if (!sourlo) return dn;      // easy: coefficient is 0
      need=3;                      // process at least 3 declets
      if (sourlo&0xc0000000) need++; // process 4 declets
      // [could reduce some more, here]
      }
     else {                        // some bits in top word, msd=0
      need=4;                      // process at least 4 declets
      if (sourhi&0x0003ff00) need++; // top declet!=0, process 5
      }
    } //msd=0

  decDigitsFromDPD(dn, sourar, need);   // process declets
  return dn;
  } // decimal64ToNumber


/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string               */
/* to-engineering-string -- conversion to numeric string              */
/*                                                                    */
/*   decimal64ToString(d64, string);                                  */
/*   decimal64ToEngString(d64, string);                               */
................................................................................
/*  d64 is the decimal64 format number to convert                     */
/*  string is the string where the result will be laid out            */
/*                                                                    */
/*  string must be at least 24 characters                             */
/*                                                                    */
/*  No error is possible, and no status can be set.                   */
/* ------------------------------------------------------------------ */
char * decimal64ToEngString(const decimal64 *d64, char *string){
  decNumber dn;                         // work
  decimal64ToNumber(d64, &dn);
  decNumberToEngString(&dn, string);
  return string;
  } // decimal64ToEngString

char * decimal64ToString(const decimal64 *d64, char *string){
  uInt msd;                        // coefficient MSD
  Int  exp;                        // exponent top two bits or full
  uInt comb;                       // combination field
  char *cstart;                    // coefficient start
  char *c;                         // output pointer in string
  uInt *pu;                        // work
  char *s, *t;                     // .. (source, target)
  Int  dpd;                        // ..
  Int  pre, e;                     // ..
  const uByte *u;                  // ..

  uInt sourar[2];                  // source 64-bit
  #define sourhi sourar[1]         // name the word with the sign
  #define sourlo sourar[0]         // and the lower word

  // load source from storage; this may be endian, or not
  #if DECENDIAN
  // DECENDIAN -- direct load, in the right order
  pu=(uInt *)d64->bytes;           // overlay
  if (LITEND) {
    sourlo=pu[0];                  // directly load the low int
    sourhi=pu[1];                  // then the high int
    }
   else {
    sourhi=pu[0];                  // directly load the high int
    sourlo=pu[1];                  // then the low int
    }
  #else
  // not DECENDIAN -- use network byte order
  if (LITEND) {                    // little-endian needs reversal
    const uByte *pb;               // work
    Int off;                       // ..
    for (pb=d64->bytes; pb<=&d64->bytes[7]; pb++) {
      off=1-((pb-d64->bytes)>>2);  // 1 then 0
      sourar[off]<<=8;
      sourar[off]|=*pb;
      } // i
    }
   else { // big-endian; it's the right way round already
    pu=(uInt *)d64->bytes;         // overlay
    sourhi=pu[0];                  // directly load the high int
    sourlo=pu[1];                  // then the low int
    }
  #endif

  c=string;                        // where result will go
  if (((Int)sourhi)<0) *c++='-';   // handle sign

  comb=(sourhi>>26)&0x1f;          // combination field
  msd=COMBMSD[comb];               // decode the combination field
  exp=COMBEXP[comb];               // ..

  if (exp==3) {
    if (msd==0) {                  // infinity
      strcpy(c, "Infinity");
      return string;               // easy
      }
    if (sourhi&0x02000000) *c++='s'; // sNaN
    strcpy(c, "NaN");              // complete word
    c+=3;                          // step past
    if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; // zero payload
    // otherwise drop through to add integer; set correct exp
    exp=0; msd=0;                  // setup for following code
    }
   else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias;

  // convert 16 digits of significand to characters
  cstart=c;                        // save start of coefficient
  if (msd) *c++='0'+(char)msd;     // non-zero most significant digit

  // Now decode the declets.  After extracting each one, it is
  // decoded to binary and then to a 4-char sequence by table lookup;
  // the 4-chars are a 1-char length (significant digits, except 000
  // has length 0).  This allows us to left-align the first declet
  // with non-zero content, then remaining ones are full 3-char
  // length.  We use fixed-length memcpys because variable-length
  // causes a subroutine call in GCC.  (These are length 4 for speed
  // and are safe because the array has an extra terminator byte.)
  #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];                   \
                   if (c!=cstart) {memcpy(c, u+1, 4); c+=3;}      \
                    else if (*u)  {memcpy(c, u+4-*u, 4); c+=*u;}

  dpd=(sourhi>>8)&0x3ff;                     // declet 1
  dpd2char;
  dpd=((sourhi&0xff)<<2) | (sourlo>>30);     // declet 2
  dpd2char;
  dpd=(sourlo>>20)&0x3ff;                    // declet 3
  dpd2char;
  dpd=(sourlo>>10)&0x3ff;                    // declet 4
  dpd2char;
  dpd=(sourlo)&0x3ff;                        // declet 5
  dpd2char;

  if (c==cstart) *c++='0';         // all zeros -- make 0

  if (exp==0) {                    // integer or NaN case -- easy
    *c='\0';                       // terminate
    return string;
    }

  /* non-0 exponent */
  e=0;                             // assume no E
  pre=c-cstart+exp;
  // [here, pre-exp is the digits count (==1 for zero)]
  if (exp>0 || pre<-5) {           // need exponential form
    e=pre-1;                       // calculate E value
    pre=1;                         // assume one digit before '.'
    } // exponential form

  /* modify the coefficient, adding 0s, '.', and E+nn as needed */
  s=c-1;                           // source (LSD)
  if (pre>0) {                     // ddd.ddd (plain), perhaps with E
    char *dotat=cstart+pre;
    if (dotat<c) {                 // if embedded dot needed...
      t=c;                              // target
      for (; s>=dotat; s--, t--) *t=*s; // open the gap; leave t at gap
      *t='.';                           // insert the dot
      c++;                              // length increased by one
      }

    // finally add the E-part, if needed; it will never be 0, and has
    // a maximum length of 3 digits
    if (e!=0) {
      *c++='E';                    // starts with E
      *c++='+';                    // assume positive
      if (e<0) {
        *(c-1)='-';                // oops, need '-'
        e=-e;                      // uInt, please
        }
      u=&BIN2CHAR[e*4];            // -> length byte
      memcpy(c, u+4-*u, 4);        // copy fixed 4 characters [is safe]
      c+=*u;                       // bump pointer appropriately
      }
    *c='\0';                       // add terminator
    //printf("res %s\n", string);
    return string;
    } // pre>0

  /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
  t=c+1-pre;
  *(t+1)='\0';                          // can add terminator now
  for (; s>=cstart; s--, t--) *t=*s;    // shift whole coefficient right
  c=cstart;
  *c++='0';                             // always starts with 0.
  *c++='.';
  for (; pre<0; pre++) *c++='0';        // add any 0's after '.'
  //printf("res %s\n", string);
  return string;
  } // decimal64ToString

/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string                        */
/*                                                                    */
/*   decimal64FromString(result, string, set);                        */
/*                                                                    */
/*  result  is the decimal64 format number which gets the result of   */
................................................................................
  #endif
  } // decimal64Show
#endif

/* ================================================================== */
/* Shared utility routines and tables                                 */
/* ================================================================== */

// define and include the conversion tables to use for shared code

#if DECDPUN==3
  #define DEC_DPD2BIN 1
#else
  #define DEC_DPD2BCD 1
#endif
#include "decDPD.h"           // lookup tables

................................................................................
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work)    */
/*                                                                    */
/*      COMBEXP - 2-bit most-significant-bits of exponent             */
/*                [11 if an Infinity or NaN]                          */
/*      COMBMSD - 4-bit most-significant-digit                        */
/*                [0=Infinity, 1=NaN if COMBEXP=11]                   */
/*                                                                    */
/* Both are indexed by the 5-bit combination field (0-31)             */
/* ------------------------------------------------------------------ */
const uInt COMBEXP[32]={0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
                        2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 3, 3};
const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
                        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1};

/* ------------------------------------------------------------------ */

Changes to decNumber/readme.txt.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
decNumber is distributed in three forms; as a complete package from
the IBM alphaWorks site (available under either a trial or a
commercial license), as a complete package from the International
Components for Unicode (ICU) site (under an as-is license), or as a
collection of Open Source files from the GCC source repository (under
the GPL license).

If you are using the Open Source copy, you can obtain the
documentation, the example files mentioned below, and this readme
from:

  http://www2.hursley.ibm.com/decimal/#decNumber

(the URL for the open source files is also linked from there).


The alphaWorks and ICU packages
................................................................................
-------------------------------

The alphaWorks and ICU packages include the files:

  *  readme.txt (this file)

  *  alphaWorks-license-files.zip (contains the 90-day trial license, in
     multiple languages) or ICU-license.html

     Note: a commercial license for this code is also available by
     following the 'License this technology' link from the alphaWorks
     page: http://www.alphaWorks.ibm.com/tech/decnumber

  *  decNumber.pdf (documentation)








|
|
<







 







|







5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
decNumber is distributed in three forms; as a complete package from
the IBM alphaWorks site (available under either a trial or a
commercial license), as a complete package from the International
Components for Unicode (ICU) site (under an as-is license), or as a
collection of Open Source files from the GCC source repository (under
the GPL license).

If you are using the GCC files, you can obtain the documentation, the
example files mentioned below, and this readme from:


  http://www2.hursley.ibm.com/decimal/#decNumber

(the URL for the open source files is also linked from there).


The alphaWorks and ICU packages
................................................................................
-------------------------------

The alphaWorks and ICU packages include the files:

  *  readme.txt (this file)

  *  alphaWorks-license-files.zip (contains the 90-day trial license, in
     multiple languages), or ICU-license.html

     Note: a commercial license for this code is also available by
     following the 'License this technology' link from the alphaWorks
     page: http://www.alphaWorks.ibm.com/tech/decnumber

  *  decNumber.pdf (documentation)

Changes to doc/ldecNumber.odt.

cannot compute difference between binary files

Added doc/ldecNumber.pod.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
=pod

=head1 NAME

B<ldecNumber> - a Lua 5.1 wrapper for the Decimal Number library 
B<decNumber>

=head1 OVERVIEW

The B<ldecNumber> package is a Lua module for General Decimal Arithmetic.
For the background and rationale for the design of the arithmetic, see 
Decimal Floating-Point: Algorism for Computers in the Proceedings of 
the 16th IEEE Symposium on Computer Arithmetic (Cowlishaw, M. F., 
2003). L<http://www2.hursley.ibm.com/decimal/IEEE-cowlishaw-arith16.pdf>
The B<decNumber> package, an arbitrary-precision implementation of 
the specifications in ANSI C, provides a reference implementation for 
both the arithmetic and the encodings, and is used as the basis for 
the B<ldecNumber> package. See Mike Cowlishaw's decimal page 
L<http://www2.hursley.ibm.com/decimal/> 
for more information and the latest versions of the B<decNumber> 
package and test code.

The B<ldecNumber> package was designed to provide the arithmetic 
facilities of the B<decNumber> package with a Lua flavor. It is a 
loadable Lua module, designed for Lua 5.1.

=head1 DOWNLOAD

B<ldecNumber> source code can be downloaded from its 
LuaForge (L<http://luaforge.net/projects/ldecnumber/>) page.

The source code from the B<decNumber> package and the decTest package are 
included in the B<ldecNumber> distribution for a few reasons:

=over4

=item 1

A couple of minor modifications were made to decTest to correct syntax 
errors.

=item 2

The B<decNumber> package is fairly small, and including it is a 
convenience to users as well as a means of documenting exactly the 
code used to build and test the B<ldecNumber> package

=item 3

IBM's liberal ICU License allows me to do so!

=back

The distribution also includes a copy of the decNumber C library 
User's Guide, I<decNumber.pdf>. This is the best reference for the 
specification of most of the functions included in the C<decNumber> 
module.

=head1 INSTALLATION

A I<Makefile> is provided. 

=head1 IMPLEMENTATION

A few arbitrary choices were made in the implementation of the Lua 
wrapper.

=head2 Precision

The size of structures used in the B<decNumber> package determines the 
maximum number of decimal digits in decimal numbers it can manipulate.  
The default build of the C<decNumber> module is configured for 69 digits. 
This number was chosen for a couple reasons: the resulting structure 
size is between 57 and 64 bytes in size (so each decimal number takes 
this this much space), and this precision is a bit more than twice 
what is needed for Decimal128 external format. Providing twice the 
external format's precision seemed like a good practice for mitigation 
of rounding issues during calculations with these numbers.

I<Note: the B<ldecNumber> package does not yet support any external binary 
formats, such as Decimal128, though it may in the future. Presently 
Lua strings and Lua numbers are the only "external" formats.>

In any case, you may change the value of C<DECNUMDIGITS> during a build 
of  the C<decNumber> module to accommodate more digits, or reduce memory 
overhead if you need fewer digits. The  C<decNumber> module has only been 
tested with the default setting, and one or two others.

=head2 Context

The decNumber context provides configuration settings such as working 
precision and rounding mode, and also holds condition flags. Functions 
in the B<decNumber> package take a context argument. Using this approach 
in Lua would have made infix operator syntax impossible. This would 
not have been very Lua-like.

Instead, the  C<decNumber> module automatically maintains a decNumber 
context per Lua thread. This thread decNumber context may be modified 
and inspected. It may also be retrieved and restored, so threads may 
maintain multiple contexts if desired. Modifications to the context 
in one thread do not affect the contexts in other threads, unless, of 
course, threads explicitly retrieve, exchange, and replace their 
contexts with a shared context. (If you don't use setcontext you 
don't need to worry!)

The default decNumber context is C<DEC_INIT_DECIMAL128> as described  
in I<decNumber.pdf>. This default may be changed during a build of the 
C<decNumber> module by changing the value of C<LDN_CONTEXT_DEFAULT>. 
The context method setdefault may be used to initialize a context to 
one of the well known default configurations.

=head2 Naming Convention

Names in the B<decNumber> package follow a convention of a 
C<decNumber> or C<DEC_> prefix and mixed case, or for some constants, 
upper case. Lua code, on the other hand, tends toward lower case 
identifiers. I attempted to unify this by 

=over 4

=item *

using C<decNumber> as the module name 

=item *

stripping the prefix described above from the function 
names and constants (since the module name prefix will typically be 
there anyway)

=item *

using lower case for function names, but otherwise 
retaining the spelling, and 

=item *

retaining the case for constant names

=back

Wherever there was a predefined Lua metamethod, e. g., C<__add>, the 
appropriate function is bound to that name as well as the B<decNumber> 
package function name.

Where it seemed appropriate, functions are provided both as methods 
on decimal numbers, as well as functions in the C<decNumber> module.

=head2 Mutability

The decimal numbers created by Lua are not mutable. This decision 
was based on my judgment that the potential performance benefit, 
mainly lower memory consumption and less garbage collection, was 
outweighed by the safety and lack of “surprise” that immutability 
provides. This makes decimal numbers compatible with Lua numbers 
and strings, both of which are also not mutable.

=head2 Conversion

All the functions in the C<decNumber> module automatically convert 
their arguments from Lua numbers or strings as necessary to perform 
the operation. This conversion is done with the current settings in 
the thread decNumber context.

=head1 EXAMPLES

The distribution contains an I<examples> directory with Lua 
translations of some of the C examples from the B<decNumber> package.

=head1 VERIFICATION TESTS

The distribution contains a test directory with a few test files.

=head2 Unit Tests

File: I<ldecNumberUnitTest.lua>

This is a small but expanding set of unit tests for the C<decNumber> 
module. It uses the lunit module that can be obtained from Mike 
Roth's page L<http://www.nessie.de/mroth/lunit/>.

File: I<ldecNumberGausstest.lua>

This is a small small tests for the 
L<C<decNumber.randomstate>|/decNumber.randomstate> 
function and use of L<Random States>. It defines a Gaussian random
number generator, and tests it by graphing the result of many
executions. It uses the B<Lua DISLIN> library for graphing, see
LuaForge for Lua DISLIN 
L<http://luaforge.net/projects/ldislin/files>.

File: I<ldecNumberThreadsTest.lua>

This is a simple test that the decimal context in each thread is 
independent. It requires visual inspection of the results to verify 
that thread 1 is rounding ROUND_HALF_DOWN and thread 2 is rounding 
ROUND_HALF_EVEN.

=head2 Performance Tests

File: I<ldecNumberPerf.lua>

This is a simple test of the speed of some arbitrary C<decNumber> 
module functions. It was useful to confirm that  decimal context 
caching was worthwhile. It relies on the lperformance module, which 
is included, but has been designed for WindowsXP.

=head2 Compliance Test

File: I<ldecNumberTestDriver.lua>

This is the big test. It uses dectest sources from IBM, and has 
over 25,000 test cases. The Lua file is a driver to execute the tests 
specified by dectest.

Since version 10 of the Lua C<decNumber> module, the results for this 
test are: 

C<For all 26205 tests, 26047 succeeded, 5 failed, 54 failed(conv), 69 skipped(#), 30 skipped(prec).>

This is as good as possible with the default configuration. What this means is:

	26047 succeeded	woot!
	5 failed	these 5 tests are know to fail in the decNumber C library;
             these edge cases are under reconsideration in the Decimal Number Specification
	54 failed(conv)	 the precision required for the operands is insufficient in the Lua wrapper
	69 skipped(#)	 the test is for NULL arguments or format conversions not supported
	30 skipped(prec) the test called for a  precision larger than provided in the Lua wrapper

=head1 REFERENCE

Here is a reference to the data types, constants, and functions in the 
C<decNumber> module. Many of these will refer to the decNumber C library 
User's Guide, I<decNumber.pdf>, for implementation details.

The C<decNumber> module defines three userdata types with their own 
metatables. These are L</Decimal Numbers>, L</Decimal Contexts>, and 
decimal L</Random States>.

=head1 Decimal Numbers

Decimal numbers are immutable numeric values. In the default 
configuration they can have up to 69 digits of precision, and 
exponents of -999999999 to 999999999.

Decimal numbers are created by the functions in the C<decNumber> 
module. Since any arguments to these functions may be strings, 
Lua numbers, or decimal numbers, conversion from strings or 
Lua numbers to decimal numbers can be achieved in may ways. 
The function L<C<decNumber.tonumber>|/decNumber.tonumber> is 
the most obvious.

In the descriptions below, arguments or results that may be a 
string, Lua number, or decimal number are indicated by <decarg> 
whereas arguments or results that must be a  decimal number 
are indicated by C<decnum>.

The metatable for decimal numbers is available as 
C<decNumber.number_metatable>.

=head1 Decimal Contexts

Decimal contexts are mutable records that contain 

=over 4

=item *

flags that control behaviors of the C<decNumber> module, such as 
precision and rounding

=item *

conditions that report the status of sequence of operations, 
such as overflow

=back

See L</Context> for some rational on how the C<decNumber> 
module manages contexts.

In the descriptions below, arguments or results that must be a  
decimal context are indicated by C<decctx>.

The metatable for decimal contexts is available as 
C<decNumber.context_metatable>.

=head1 Random States

Random states are mutable records that contain opaque data for 
generation of random numbers.

See L</Operations on Random States> for the description of 
functions for creating and using random states.

In the descriptions below, arguments or results that must be a  
decimal context are indicated by C<decrst>.

The metatable for decimal contexts is available as 
C<decNumber.drandom_metatable>.

=head1 Constants

Here are the constants exposed in the C<decNumber> module from the 
B<decNumber> package.

=head1 Rounding

These numeric flags are used with 
L<C<decctx:setround(x)>|/decctx:setround>

    decNumber.ROUND_CEILING     round towards +infinity
    decNumber.ROUND_UP          round away from 0
    decNumber.ROUND_HALF_UP     0.5 rounds up
    decNumber.ROUND_HALF_EVEN   0.5 rounds to nearest even
    decNumber.ROUND_HALF_DOWN   0.5 rounds down
    decNumber.ROUND_DOWN        round towards 0 (truncate)
    decNumber.ROUND_FLOOR       round towards -infinity

=head1 Status Flags

These numeric status flags are used with 
L<C<decctx:getstatus()>|/decctx:getstatus>

    decNumber.Conversion_syntax
    decNumber.Division_by_zero
    decNumber.Division_impossible
    decNumber.Division_undefined
    decNumber.Insufficient_storage
    decNumber.Inexact
    decNumber.Invalid_context
    decNumber.Invalid_operation
    decNumber.Overflow
    decNumber.Clamped
    decNumber.Rounded
    decNumber.Subnormal
    decNumber.Underflow

These constants are combinations of the above status flags:

    decNumber.IEEE_854_Division_by_zero
    decNumber.IEEE_854_Inexact
    decNumber.IEEE_854_Invalid_operation
    decNumber.IEEE_854_Overflow
    decNumber.IEEE_854_Underflow
    decNumber.Errors       normally errors (results are qNaN, infinite, or 0)
    decNumber.NaNs         cause a result to become qNaN
    decNumber.Information  normally for information only (have finite results)

=head1 Initialization Descriptors

These constants are used with 
L<C<decctx:setdefault(x)>|/decctx:setdefault>

    decNumber.INIT_BASE
    decNumber.INIT_DECIMAL32
    decNumber.INIT_DECIMAL64
    decNumber.INIT_DECIMAL128

See note re: C<decNumber.INIT_BASE> and traps, below in 
L<C<decctx:setdefault(x)>|/decctx:setdefault>

=head1 Compile time configuration

These constants provide information about the compile time 
configuration.

    decNumber.MAX_DIGITS  constant DECNUMDIGITS, the maximum precision

    decNumber.version     a string with the decNumber module version information

=head1 Operations on Contexts

The following functions operate on decimal contexts. See the 
decNumber C library User's Guide, I<decNumber.pdf> for details 
about contexts, and constants used for manipulating them.

=head2 C<decNumber.getcontext>

    decNumber.getcontext ()

Returns the thread's current decimal context.

=head2 C<decctx:duplicate>

    decctx:duplicate()

Returns a copy of the decimal context argument. This may be used, 
for example, to save and restore a context around temporary 
modifications, or to keep multiple decimal contexts on hand for 
quick wholesale context changes (rather than changing individual 
fields). You probably don't ever need to do this!

=head2 C<decctx:setcontext>

    decNumber.setcontext (decctx)
    decctx:setcontext ()

Sets the thread's decimal context to the argument, and returns 
the previous decimal context, i. e., the one that was just replaced. 
You probably don't ever need to do this!

=head2 C<decctx:setdefault>

    decctx:setdefault (initconst)

Initializes the context argument to the settings specified by the 
initconst. See L</Initialization Descriptors> for permitted values for 
initconst. No values are returned.

Note: since traps are not supported, C<decNumber.INIT_BASE> differs 
from the behavior documented in the decNumber C library User Guide in 
that it leaves traps disabled.

Uses the C library function C<decContextDefault()>.

=head2 C<decctx:getclamp>

    decctx:getclamp ()

Returns the integer value of the C<clamp> field of the context 
argument. When 0, a result exponent is limited to C<emax> (for 
example, the exponent of a zero result will be clamped to this value). 
When 1, a result exponent is limited to C<emax-(digits-1)>.

=head2 C<decctx:getdigits>

    decctx:getdigits ()

Returns the integer value of the C<digits> field of the context 
argument. This is the working precision for this decimal context. 
The results of decimal number operations will be rounded to this 
length if necessary. 

=head2 C<decctx:getemax>

    decctx:getemax ()

Returns the integer value of the C<emax> field of the context 
argument. This is the magnitude of the largest adjusted exponent 
that is permitted.

=head2 C<decctx:getemin>

    decctx:getemin ()

Returns the integer value of the C<emin> field of the context 
argument. This is the smallest adjusted exponent that is permitted 
for normal numbers.

=head2 C<decctx:getround>

    decctx:getround ()

Returns the integer value of the C<round> field of the context 
argument. See L</Rounding> for possible values.

=head2 C<decctx:getstatus>

    decctx:getstatus ()

Returns the integer value of the C<status> field of the context 
argument. See L</Status Flags> for possible values. In general, 
the result will be a bitwise-or of a subset of these values.

=head2 C<decctx:getstatusstring>

    decctx:getstatusstring ()

Returns a string derived from the present value of the context 
argument's status field using the C library function 
C<decContextStatusToString()>.

=head2 C<decctx:gettraps>

    decctx:gettraps ()

Returns 0 (we hope!) since traps are not implemented in the 
Lua wrapper - use the status flags instead!

=head2 C<decctx:setclamp>

    decctx:setclamp (num)

Sets the integer value of the C<clamp> field of the context 
argument to C<num>. When 0, a result exponent is limited to 
C<emax> (for example, the exponent of a zero result will be 
clamped to this value). When 1, a result exponent is limited 
to C<emax - (digits - 1)>.

Returns the previous value of the C<clamp> field.

Note that it is an error if num is not one of the values 0 or 1.

=head2 C<decctx:setdigits>

    decctx:setdigits (num)

Sets the integer value of the C<digits> field of the context 
argument to C<num>. This is the working precision for this 
decimal context. The results of subsequent decimal number 
operations will be rounded to this length if necessary.

Returns the previous value of the C<digits> field.

Note that it is an error if num exceeds C<decNumber.MAX_DIGITS>.

=head2 C<decctx:setemax>

    decctx:setemax (num)

Sets the integer value of the C<emax> field of the context 
argument to C<num>. This is the magnitude of the largest 
adjusted exponent that is permitted.

Returns the previous value of the C<emax> field.

Note that it is an error if num is outside the range 
0 though 999,999,999.

=head2 C<decctx:setemin>

    decctx:setemin (num)

Sets the integer value of the C<emin> field of the context 
argument to C<num>. This is the smallest adjusted exponent 
that is permitted for normal numbers. C<emin> will usually equal 
C<-emax>, but when a compressed format is used it will be 
C<-(emax-1)>.

Returns the previous value of the C<emin> field.

Note that it is an error if num is outside the range 
-999,999,999 though 0.

=head2 C<decctx:setround>

    decctx:setround (rounding)

Sets the integer value of the C<round> field of the context 
argument to C<rounding>. This is used to select the rounding 
algorithm to be used if rounding is necessary during subsequent 
decimal number operations.

Returns the previous value of the C<round> field.

Note that it is an error if rounding is not one of the values 
described in L</Rounding>.

=head2 C<decctx:setstatus>

    decctx:setstatus (flags)

Sets the integer value of the C<status> field of the context 
argument to C<flags>. See L</Status Flags> for possible values. 
In general, the flags will be a bitwise-or of a subset of these 
values. Usually the C<flags> are 0 to clear all conditions.

Returns the previous value of  the status  field.

Note that it is an error if flags is not a bitwise-or of a subset 
of the values in L</Status Flags>.

=head2 C<decctx:setstatusstring>

    decctx:setstatusstring (flagname)

Sets the decimal context's status bit corresponding to the name 
string argument C<flagname> using the C library function 
C<decContextSetStatusFromString()>.

=head2 C<decctx:settraps>

    decctx:settraps (flags)

Sets the integer value of the C<traps> field of the context 
argument to C<flags>. 

Note that it is an error if C<flags> is not zero since traps 
are not implemented in the Lua wrapper - use the status 
flags instead!

=head1 Operations on Numbers

The following functions operate on decimal numbers. In the 
descriptions below, arguments or results that may be a string, 
Lua number, or decimal number are indicated by C<decarg> whereas 
arguments or results that must be a decimal number are indicated by 
C<decnum>. See L</Decimal Numbers>.

See the decNumber C library User's Guide, I<decNumber.pdf> for 
details about limitations of the functions, and behavior in 
exceptional situations.

B<Conversions>

=head2 C<decnum:__concat>

    decnum:__concat (<string>)

Returns a string representing the value of the decimal number 
argument concatenated with the string argument. See 
L<C<decnum:tostring>|/decnum:tostring> below for a description 
of the conversion operation.

Note that by binding the method __concat to this function, the 
Lua C<..> concatenation operator will work with a decimal number 
and a string, in either order, due to Lua's internal application 
of this method when one side of the C<..> concatenation operator 
is a decimal number. 

Uses the C library function C<decNumberToString()>.

=head2 C<decnum:toengstring>

    decnum:toengstring ()
    decNumber.toengstring (decarg)

Returns a string representing the value of the argument (converted 
to a decimal number first if necessary) using engineering notation 
(where the exponent will be a multiple of three, and there may be 
up to three digits before any decimal point) if an exponent is needed. 
It implements the to-engineering-string conversion.

Uses the C library function decNumberToEngString().

=head2 C<decNumber.tonumber>

    decNumber.tonumber (decarg)

Returns a decimal number. If the argument is a decimal number, it is 
simply returned. If the argument is a Lua number or string, it is 
converted, using the present decimal context as usual, to a decimal 
number and this value is returned.

Uses the C library function C<decNumberFromString()>.

=head2 C<decnum:tostring>

    decnum:tostring ()
    decnum:__tostring ()
    decNumber.tostring (decarg)

Returns a string representing the value of the argument (converted to 
a decimal number first if necessary) using scientific notation if an 
exponent is needed (that is, there will be just one digit before any 
decimal point). It implements the to-scientific-string conversion.

Note that by binding the method C<__tostring> to this function, the 
Lua C<print> and C<tostring> functions will work with decimal numbers, 
using this conversion function.

Uses the C library function C<decNumberToString()>.

B<Operations>

=head2 C<decnum:abs>

    decnum:abs ()
    decNumber.abs (decarg)

Returns a decimal number that is the absolute value of the argument.

Uses the C library function C<decNumberAbs()>.

=head2 C<decnum:add>

    decnum:add (decarg)
    decnum:__add (decarg)
    decNumber.add (decarg, decarg)

Returns a decimal number that is the sum of its arguments.

Note that by binding the method C<__add> to this function, the 
Lua addition operator (C<+>) may be used with a C<decnum> on the 
left and a C<decarg> on the right.

Uses the C library function C<decNumberAdd()>.

=head2 C<decnum:divide>

    decnum:divide (decarg)
    decnum:__div (decarg)
    decNumber.divide (decarg, decarg)

Returns a decimal number that is the left (1st) argument divided 
by the right (2nd) argument.

Note that by binding the method C<__div> to this function, the 
Lua division operator (C</>) may be used with a C<decnum> on the 
left and a C<decarg> on the right.

Uses the C library function C<decNumberDivide()>.

=head2 C<decnum:divideinteger>

    decnum:divideinteger (decarg)
    decNumber.divideinteger (decarg, decarg)

Returns a decimal number that is the integer part of the result 
of dividing of its arguments. Note that, per the B<decNumber> 
specification, this is a convert to integer by truncation. If 
you want some other rounding mode, use L<C<decnum:floor>|/decnum:floor>, 
or for any rounding mode use 
L<C<decnum:tointegralvalue>|/decnum:tointegralvalue>
or L<C<decnum:quantize>|/decnum:quantize>.

Uses the C library function C<decNumberDivideInteger()>.

=head2 C<decnum:exp>

    decnum:exp ()
    decNumber.exp (decarg)

Returns a decimal number that is e raised to the power of the argument.

Uses the C library function C<decNumberExp()>. 

=head2 C<decnum:floor>

    decnum:floor (decarg)
    decNumber.floor (decarg, decarg)

Returns a decimal number integer that is the floor of the left (1st) 
argument divided by the right (2nd) argument. Contrast this with 
L<C<decnum:divideinteger>|/decnum:divideinteger> which uses truncation.

The floor function is implemented as equal to 
L<C<decnum:divideinteger>|/decnum:divideinteger> if the signs of the 
arguments are the same or if the remainder is zero, otherwise as equal 
to the L<C<decnum:divideinteger>|/decnum:divideinteger> result minus 1. 
The current context's rounding mode is used. 
See L<C<decnum:mod>|/decnum:mod>.

Uses the C library function C<decNumberDivideInteger()>, and then 
C<decNumberMultiply()> followed by C<decNumberCompare() decNumberIsZero()> 
to check if the remainder is zero, and C<decNumberSubtract()>.

=head2 C<decnum:ln>

    decnum:ln ()
    decNumber.ln (decarg)

Returns a decimal number that is the natural logarithm (logarithm in 
base e) of the argument.

Uses the C library function C<decNumberLn()>.

=head2 C<decnum:log10>

    decnum:log10 ()
    decNumber.log10 (decarg)

Returns a decimal number that is the logarithm in base ten of the 
argument.

Uses the C library function C<decNumberLog10()>.

=head2 C<decnum:max>

    decnum:max (decarg)
    decNumber.max (decarg, decarg)

Returns a decimal number that is the maximum of its arguments.

Uses the C library function C<decNumberMax()>.

=head2 C<decnum:min>

    decnum:min (decarg)
    decNumber.min (decarg, decarg)

Returns a decimal number that is the minimum of its arguments.

Uses the C library function C<decNumberMin()>.

=head2 C<decnum:minus>

    decnum:minus ()
    decnum:__unm ()
    decNumber.minus (decarg)

Returns a decimal number that is the result of subtracting 
the argument from 0.

Note that by binding the method C<__unm> to this function, the 
Lua unary minus operator (C<->) may be used with decimal numbers.

Uses the C library function C<decNumberMinus()>.

=head2 C<decnum:mod>

    decnum:mod (decarg)
    decnum:__mod (decarg)
    decNumber.mod (decarg, decarg)

Returns a decimal number that is remainder of the left (1st) 
argument divided by the right (2nd) argument based on Lua rules 
for the mod operator (C<%>). Lua defines

    a % b == a - floor(a/b)*b

whereas the General Decimal Arithmetic Specification defines 
remainder using truncation. 

The C<mod> function is implemented as equal to 
L<C<decnum:remainder>|/decnum:remainder> if the signs of the 
arguments are the same or the remainder is zero, otherwise as 
equal to the remainder plus the divisor. The current context's 
rounding mode is used.

Note that by binding the method C<__mod> to this function, the 
Lua modulo operator (C<%>) may be used with a C<decnum> on the 
left and a C<decarg> on the right.

Uses the C library functions C<decNumberRemainder()>, 
C<decNumberIsNegative()>, C<decNumberIsZero()>, and C<decNumberAdd()>.

=head2 C<decnum:multiply>

    decnum:multiply (decarg)
    decnum:__mul (decarg)
    decNumber.multiply (decarg, decarg)

Returns a decimal number that is the product of its arguments.

Note that by binding the method C<__mul> to this function, the Lua 
multiplication operator (C<*>) may be used with a C<decnum> on the 
left and a C<decarg> on the right.

Uses the C library function C<decNumberMultiply()>.

=head2 C<ddecnum:normalize>

    decnum:normalize ()
    decNumber.normalize (decarg)

Returns a decimal number that is the result of adding the argument 
to 0, and putting the result in its simplest form. That is, a non-zero 
number which has any trailing zeros in the coefficient has those zeros 
removed by dividing the coefficient by the appropriate power of ten 
and adjusting the exponent accordingly, and a zero has its exponent 
set to 0. 

Uses the C library function C<decNumberNormalize()>.

=head2 C<decnum:plus>

    decnum:plus ()
    decNumber.plus (decarg)

Returns a decimal number that is the result of adding the argument 
to 0. This takes place according to the settings given in the 
decimal context, following the usual arithmetic rules. This may 
therefore be used for rounding.

Uses the C library function C<decNumberPlus()>.

=head2 C<decnum:power>

    decnum:power (decarg)
    decnum:__pow (decarg)
    decNumber.power (decarg, decarg)

Returns a decimal number that is the left (1st) argument raised to 
the power of the right (2nd) argument.

Note that by binding the method C<__pow> to this function, the Lua 
power operator (C<^>) may be used with a C<decnum> on the left 
and a C<decarg> on the right.

Uses the C library function C<decNumberPower()>.

=head2 C<decnum:quantize>

    decnum:quantize (decarg)
    decNumber.quantize (decarg, decarg)

Returns a decimal number that is numerically equal (except for 
any rounding) to the left (1st) argument but modified so its 
exponent has a specific value, equal to that of the right (2nd) 
argument. To achieve this, the coefficient of the result is 
adjusted (by rounding or shifting) so that its exponent has the 
requested value. For example, if the left (1st) argument had 
the value 123.4567, and the right (2nd) argument had the 
value 0.12, the result would be 123.46 (that is, 12346 with an 
exponent of -2, matching the right (2nd) argument).

Uses the C library function C<decNumberQuantize()>.

=head2 C<decnum:remainder>

    decnum:remainder (decarg)
    decNumber.remainder (decarg, decarg)

Returns a decimal number that is the remainder of the left (1st) 
argument divided by the right (2nd) argument. The identity

    lhs == (lhs:divideinteger(rhs) * rhs) + lhs:remainder(rhs)

holds.

Uses the C library function C<decNumberRemainder()>.

=head2 C<decnum:remaindernear>

    decnum:remaindernear (decarg)
    decNumber.remaindernear (decarg, decarg)

Returns a decimal number that is the remainder of the left (1st) 
argument divided by the right (2nd) argument using the rules 
defined in IEEE 854. This follows the same definition as 
L<C<decnum:remainder>|/decnum:remainder>, except that the nearest 
integer quotient (or the nearest even integer if the remainder 
is equidistant from two) is used instead of the result from 
L<C<decnum:divideinteger>|/decnum:divideinteger>.

For example, C<decNumber.remaindernear(10, 6)> has the result -2 
(instead of 4) because the multiple of 6 nearest to 10 is 12 
(rather than 6).

Uses the C library function C<decNumberRemainderNear()>.

=head2 C<decnum:rescale>

    decnum:rescale (decarg)
    decNumber.rescale (decarg, decarg)

Returns a decimal number that is numerically equal (except for 
any rounding) to the left (1st) argument but modified so its exponent 
has the value of the right (2nd) argument. See 
L<C<decnum:quantize>|/decnum:quantize>. 
The right (2nd) argument must be a whole number (before any rounding); 
that is, any digits in the fractional part of the number must be zero.

Uses the C library function C<decNumberRescale()>.

=head2 C<decnum:samequantum>

    decnum:samequantum (decarg)
    decNumber.samequantum (decarg, decarg)

Returns the decimal number 1 when the exponents of the arguments are 
equal, or if they are both Infinities or they are both NaNs; in all 
other cases returns the decimal number 0. This function is used to 
test whether the exponents of two numbers are equal. The coefficients 
and signs of the arguments are ignored.

Uses the C library function C<decNumberSameQuantum()>.

=head2 C<decnum:squareroot>

    decnum:squareroot ()
    decNumber.squareroot (decarg)

Returns a decimal number that is the square root of its argument, 
rounded if necessary using the digits setting in the decimal context 
and using the round-half-even rounding algorithm.

Uses the C library function C<decNumberSquareRoot()>.

=head2 C<decnum:subtract>

    decnum:subtract (decarg)
    decnum:__sub (decarg)
    decNumber.subtract (decarg, decarg)

Returns a decimal number that is the left (1st) argument minus the 
right (2nd) argument.

Note that by binding the method C<__sub> to this function, the Lua 
subtraction operator (C<->) may be used with a C<decnum> on the left 
and a C<decarg> on the right.

Uses the C library function C<decNumberSubtract()>.

=head2 C<decnum:tointegralvalue>

    decnum:tointegralvalue ()
    decNumber.tointegralvalue (decarg)

Returns a decimal number that is the argument with any fractional 
part removed, if necessary, using the rounding mode in the decimal 
context.

Uses the C library function C<decNumberToIntegralValue()>.

=head2 C<decnum:trim>

    decnum:trim ()
    decNumber.trim (decarg)

Returns a decimal number that is the argument with any insignificant 
trailing zeros removed. That is, if the number has any fractional 
trailing zeros they are removed by dividing the coefficient by the 
appropriate power of ten and adjusting the exponent accordingly.

Uses the C library function C<decNumberTrim()>.

B<Comparisons and Predicates>

=head2 C<decnum:compare>

    decnum:compare (decarg)
    decNumber.compare (decarg, decarg)

Returns a decimal number that is the comparison of its arguments 
numerically. If the left (1st) argument is less than the right (2nd) 
argument then the result is -1. If they are equal (that is, when 
subtracted the result would be 0), then the result is 0. If the 
left (1st) argument is greater than the right (2nd) argument then the 
result is 1. If the operands are not comparable (that is, one or both 
is a NaN) then the result is NaN.

Uses the C library function C<decNumberCompare()>.

=head2 C<decnum:comparetotal>

    decnum:comparetotal (decarg)
    decNumber.comparetotal (decarg, decarg)

Returns a decimal number that is the comparison of its arguments 
numerically using the IEEE 754r proposed ordering. The result is the 
similar to L<C<decnum:compare>|/decnum:compare> above, except that NaN 
is never returned. The total order differs from the numerical 
comparison in that:

    -NaN <  -sNaN < -Infinity < -finites < -0 < +0 < +finites < +Infinity < +sNaN < +NaN.

Also, C<1.000 < 1.0> (etc.) and NaNs are ordered by payload.

Uses the C library function C<decNumberCompareTotal()>.

=head2 C<decnum:eq>

    decnum:eq (decarg)
    decnum:__eq (decarg)
    decNumber.eq (<decarg>, <decarg>)

Returns a boolean that is true when the arguments are equal, false 
otherwise.

Note that by binding the method C<__eq> to this function, the Lua 
equality operators (C<==> and C<~=>) may be used with a C<decnum> 
on the left and a C<decnum> on the right.

Uses the C library functions C<decNumberCompare()> and 
C<decNumberIsZero()>.

=head2 C<decnum:iszero>

    decnum:iszero
    decNumber.iszero (decarg)

Returns a boolean that is true if the argument is zero, false 
otherwise

Uses the C library function C<decNumberIsZero()>.

=head2 C<decnum:isnegative>

    decnum:isnegative ()
    decNumber.isnegative (decarg)

Returns a boolean that is true if the argument is negative, false 
otherwise

Uses the C library function C<decNumberIsNegative()>.

=head2 C<decnum:isnan>

    decnum:isnan ()
    decNumber.isnan (decarg)

Returns a boolean that is true if the argument is a NaN (quiet or 
signaling), false otherwise

Uses the C library function C<decNumberIsNaN()>.

=head2 C<decnum:isqnan>

    decnum:isqnan ()
    decNumber.isqnan (decarg)

Returns a boolean that is true if the argument is a quiet NaN, 
false otherwise

Uses the C library function C<decNumberIsQNaN()>.

=head2 C<decnum:issnan>

    decnum:issnan ()
    decNumber.issnan (decarg)

Returns a boolean that is true if the argument is a signaling NaN, 
false otherwise

Uses the C library function C<decNumberIsSNaN()>.

=head2 C<decnum:isinfinite>

    decnum:isinfinite ()
    decNumber.isinfinite (decarg)

Returns a boolean that is true if the argument is infinite, 
false otherwise.

Uses the C library function C<decNumberIsInfinite()>.

=head2 C<decnum:le>

    decnum:le (decarg)
    decnum:__le (decarg)
    decNumber.le (<decarg>, <decarg>)

Returns a boolean that is true when left (1st) argument is less than 
or equal to the right (2nd) argument, false otherwise.

Note that by binding the method C<__le> to this function, the Lua 
comparison operators (C<E<lt>=> and C<E<gt>=>) may be used with a 
C<decnum> on the left and a C<decnum> on the right.

Uses the C library functions C<decNumberCompare()> 
C<decNumberIsNegative()> and C<decNumberIsZero()>.

=head2 C<decnum:lt>

    decnum:lt (decarg)
    decnum:__lt (decarg)
    decNumber.lt (<decarg>, <decarg>)

Returns a boolean that is true when left (1st) argument is less than 
the right (2nd) argument, false otherwise.

Note that by binding the method C<__lt> to this function, the Lua 
comparison operators (C<E<lt>> and C<E<gt>>) may be used with a 
C<decnum> on the left and a C<decnum> on the right. Lua also assumes 
that C<a E<lt>= b> is equivalent to C<not (b E<lt> a)> which in the 
presence of NaNs may or may not be what you want - if not, use 
L<C<decnum:compare>|/decnum:compare> directly.

Uses the C library functions C<decNumberCompare()> and 
C<decNumberIsNegative()>.

=head1 Operations on Random States

The following functions operate on random states.

The random number generator in the B<ldecNumber> package is based 
on a lagged Fibonacci generator ("LFIB4"). George Marsaglia has this 
to say about LFIB4:

    LFIB4 is an extension of what I have previously defined as a 
    lagged Fibonacci generator [...] I have developed the 4-lag 
    generator LFIB4 using addition [...] Its period is 2^31*(2^256-1), 
    about 2^287, and it seems to pass all tests --- in particular, 
    those of the kind for which 2-lag generators using +,-, xor 
    seem to fail.

The B<ldecNumber> package uses LFIB4 to produce a stream of bits in 
10-bit chunks. This is convenient for making decimal numbers in 
multiples of three decimal digits, and fits with the default setting 
of the B<decNumber> compile time parameter C<DECDPUN>. If you change 
C<DECDPUN> then you may not be able to use the B<ldecNumber> package's
random states without modification to the C code. There is a compile
time setting C<LDN_ENABLE_RANDOM> that should be defined to 0 to 
disable random state features.

The B<ldecNumber> package random state code has been tested with 
L'Ecuyer and Simard's TestU01 Crush -- 
see L<http://www.iro.umontreal.ca/~simardr/testu01/tu01.html>

    ========= Summary results of Crush =========
    Version:          TestU01-1.1
    Generator:        Generator dec12
    Number of statistics:  144
    Total CPU time:   02:55:11.06
    All tests were passed

While this confers a great deal of confidence in the quality of the 
generator, two caveats are in order:

=over4

=item 1.

Crush uses IEEE doubles, and so the quality of the generator with more 
than a dozen or so digits is untested, though believed to be good

=item 2.

This generator was not designed for cryptographic use, and so is 
probably only useful for its intended applications: simulation 
and testing

=back

=head2 C<decNumber.randomstate>

    decNumber.randomstate ([a [, b [, c [, d]]]])

Creates and returns a new random state C<decrst>. If any arguments 
are not supplied, defaults are provided. The arguments C<a>, C<b>, 
C<c>, and C<d> are used as inputs to the random number generator 
KISS to initialize the random state.

The random state userdata has one method: C<__call>. This means that 
the random state may be used as a function to return random values.

=head2 C<decrst:__call>

    decrst([digits [, exponent]])

Returns a new random decimal number. If supplied, C<digits> is the 
number of decimal digits in the new random decimal number; the default 
is 12. If supplied, C<exponent> is the exponent of the new random 
decimal number; the default is C<-digits> so the new random decimal 
number is between zero (inclusive) and one (exclusive).

=head1 VERSION

This is B<ldecNumber> version 19.

=head1 CREDITS

B<ldecNumber> was developed by Doug Currie, Londonderry, NH, USA.

B<decNumber> was developed by Mike Cowlishaw at IBM.

=head1 LICENSE

The B<ldecNumber> distribution includes the C source code of the wrapper
itself as a Lua module, a Makefile, examples, test code, and the 
decNumber source code from IBM. The decNumber code is licensed as 
follows (see I<ICU-license.html> in the distribution):

=head2 ICU License - ICU 1.8.1 and later

COPYRIGHT AND PERMISSION NOTICE

Copyright (c) 1995-2005 International Business Machines Corporation and others
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, provided that the above
copyright notice(s) and this permission notice appear in all copies of
the Software and that both the above copyright notice(s) and this
permission notice appear in supporting documentation.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Except as contained in this notice, the name of a copyright holder
shall not be used in advertising or otherwise to promote the sale, use
or other dealings in this Software without prior written authorization
of the copyright holder.

--------------------------------------------------------------------------------

All trademarks and registered trademarks mentioned herein are the property of 
their respective owners.

=head2 ldecNumber License

The non-IBM Lua decNumber code and documentation are:

* Copyright (c) 2006-7 Doug Currie, Londonderry, NH

and licensed under the same terms as the ICU License, above.

Added doc/pod2html.pl.















>
>
>
>
>
>
>
1
2
3
4
5
6
7
#!perl

use Pod::Html;

pod2html @ARGV;

__END__

Changes to ldecNumber.c.

1
2
3
4
5
6
7
8
9
10
11
12
..
37
38
39
40
41
42
43


44





45
46
47
48
49
50
51
52

53
54
55
56
57

58
59
60
61
62
63
64
...
601
602
603
604
605
606
607
























































































































608
609
610
611
612
613
614
...
654
655
656
657
658
659
660








661
662
663
664
665
666
667
...
800
801
802
803
804
805
806


807
808
809
810
811











812
813
814
815
816
817
818
...
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861
862
863
/* ldecNumber.c
*  Lua wrapper for decNumber
*  created September 3, 2006 by e
*
* Copyright (c) 2006 Doug Currie, Londonderry, NH
* All rights reserved.
* 
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, and/or sell copies of the Software, and to permit persons
................................................................................

#include "version.h"

// #define LDN_SEAL_TABLES // to make tables and metatables read only

// testing
// #define LDN_CACHE_TEST 1


#define LDN_ENABLE_CACHE 1






#ifndef LDN_CONTEXT_DEFAULT
#define LDN_CONTEXT_DEFAULT DEC_INIT_DECIMAL128
#endif

#define DN_NAME         "decNumber"
#define DN_CONTEXT_META " decNumber_CoNTeXT_MeTA"
#define DN_DNUMBER_META " decNumber_NuMBeR_MeTA"


#define DN_VERSION "Lua " DECFULLNAME " version " SVN_REVS " for " LUA_VERSION " with " DECVERSION

const char *dn_context_meta = DN_CONTEXT_META;
const char *dn_dnumber_meta = DN_DNUMBER_META;


// decNumber constants initialized when library loaded
static decNumber dnc_one;

static void dn_dnc_init (void)
{
    decContext dc;
................................................................................
static int dn_ctx_tostring (lua_State *L)
{
    decContext *dc = ldn_check_context (L, 1);
    const char * s = decContextStatusToString(dc);
    lua_pushfstring (L, "decNumber context (%p) %s", dc, s);
    return 1;
}

























































































































/* ************************ decNumber constants *********************** */

#define DEC_(s)  { #s, DEC_ ## s },

static const struct {
    const char* name;
................................................................................
    DEC_(INIT_DECIMAL64)
    DEC_(INIT_DECIMAL128)
    /* compile time config */
    {"MAX_DIGITS", DECNUMDIGITS },
    /* terminator */
    { NULL, 0 }
};









static const luaL_reg dn_dnumber_meta_lib[] =
{
    {"eq",              dn_eq     },
    {"lt",              dn_lt     },
    {"le",              dn_le     },
    
................................................................................

    {"getcontext",      dn_get_context   },
    {"setcontext",      dn_set_context   },
    {"tonumber",        dn_todecnumber   },
    {"tostring",        dn_string        },
    {"toengstring",     dn_engstring     },
    


#if LDN_CACHE_TEST
    {"cachestats",      dn_cache_stats   },
#endif
    {NULL, NULL}
};












LUALIB_API int luaopen_ldecNumber(lua_State *L)
{
    /* initialize constants */
    dn_dnc_init ();
    /* create a shared environment for the decNumber functions */
    lua_createtable (L, 0, 5);
................................................................................
            i += 1;
        }
    }
    lua_pushliteral (L,"version");              /** version */
    lua_pushliteral (L, DN_VERSION);
    lua_settable (L, -3);
    /* */
    lua_pushliteral ( L, "context_metatable");   /** context metatable */
    luaL_newmetatable (L, dn_context_meta);
    /* register context metatable functions */

    luaL_register(L, NULL, dn_context_meta_lib);
    lua_pushstring (L, "__index");
    lua_pushvalue (L, -2); /* push metatable */
    lua_rawset (L, -3);    /* metatable.__index = metatable */
    lua_settable(L,-3);
    /* */
    lua_pushliteral ( L, "number_metatable");   /** number metatable */
    luaL_newmetatable (L, dn_dnumber_meta);
    /* register decimal number metatable functions */
    luaL_register(L, NULL, dn_dnumber_meta_lib);
    lua_pushstring (L, "__index");
    lua_pushvalue (L, -2); /* push metatable */
    lua_rawset (L, -3);    /* metatable.__index = metatable */
    lua_settable(L,-3);

    /* */
#if LDN_SEAL_TABLES
    /* set decNumber's metatable to itself - set as readonly (__newindex) */
    lua_pushvalue(L, -1);
    lua_setmetatable(L, -2);
#endif
    return 1;
}

/* end of ldecNumber.c */




|







 







>
>

>
>
>
>
>








>





>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







>
>





>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
>
|
<
<
<
<

<
<
<
<
<
<
<
<
>










1
2
3
4
5
6
7
8
9
10
11
12
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
...
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
...
980
981
982
983
984
985
986
987
988
989
990
991




992








993
994
995
996
997
998
999
1000
1001
1002
1003
/* ldecNumber.c
*  Lua wrapper for decNumber
*  created September 3, 2006 by e
*
* Copyright (c) 2006-7 Doug Currie, Londonderry, NH
* All rights reserved.
* 
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, and/or sell copies of the Software, and to permit persons
................................................................................

#include "version.h"

// #define LDN_SEAL_TABLES // to make tables and metatables read only

// testing
// #define LDN_CACHE_TEST 1

#ifndef LDN_ENABLE_CACHE
#define LDN_ENABLE_CACHE 1
#endif

#ifndef LDN_ENABLE_RANDOM
#define LDN_ENABLE_RANDOM 1
#endif

#ifndef LDN_CONTEXT_DEFAULT
#define LDN_CONTEXT_DEFAULT DEC_INIT_DECIMAL128
#endif

#define DN_NAME         "decNumber"
#define DN_CONTEXT_META " decNumber_CoNTeXT_MeTA"
#define DN_DNUMBER_META " decNumber_NuMBeR_MeTA"
#define DN_DRANDOM_META " decNumber_RaNDoM_MeTA"

#define DN_VERSION "Lua " DECFULLNAME " version " SVN_REVS " for " LUA_VERSION " with " DECVERSION

const char *dn_context_meta = DN_CONTEXT_META;
const char *dn_dnumber_meta = DN_DNUMBER_META;
const char *dn_drandom_meta = DN_DRANDOM_META;

// decNumber constants initialized when library loaded
static decNumber dnc_one;

static void dn_dnc_init (void)
{
    decContext dc;
................................................................................
static int dn_ctx_tostring (lua_State *L)
{
    decContext *dc = ldn_check_context (L, 1);
    const char * s = decContextStatusToString(dc);
    lua_pushfstring (L, "decNumber context (%p) %s", dc, s);
    return 1;
}

/* ************************** decNumber random ************************* */

#if LDN_ENABLE_RANDOM

typedef struct random_state
{
    uint32_t r[256];       // circular vector of random values
    uint64_t bit_supply;   // a supply of bits,
    int bit_supply_bits;   // and how many bits left in it
    int x;                 // index of last used r value
} random_state;

static random_state *ldrs_check_state (lua_State *L, int index)
{
    random_state *rs = (random_state *)luaL_checkudata (L, index, dn_drandom_meta);
    if (rs == NULL) luaL_argerror (L, index, "decNumber bad random_state");
    return rs; /* leaves random_state on Lua stack */
}

static int dn_randomstate (lua_State *L)
{
    int i;
    uint64_t t, a=698769069ULL;
    uint32_t x = luaL_optinteger (L, 1, 0); /* four seed values for KISS() */
    uint32_t y = luaL_optinteger (L, 2, 0);
    uint32_t z = luaL_optinteger (L, 3, 0);
    uint32_t c = luaL_optinteger (L, 4, 0);
    random_state *rs = (random_state *)lua_newuserdata(L, sizeof(random_state));
    luaL_getmetatable (L, dn_drandom_meta);
    lua_setmetatable (L, -2); /* set metatable */
    /* seed it */
    if (x == 0) x = 123456789;
    if (y == 0) y = 362436000;
    if (z == 0) z = 521288629;
    if (c == 0) c =   7654321;
    rs->bit_supply = rs->bit_supply_bits = 0;
    rs->x = 0;
    for (i = 0; i < 256; i++)
    {
        // KISS()
        x = 69069 * x + 12345;
        y ^= (y << 13); y ^= (y >> 17); y ^= (y << 5);
        t = a * z + c; c = (t >> 32);
        rs->r[i] = x + y + (z = t);
    }
    return 1;
}

static unsigned int lfib4_10bits (random_state *rs)
{
    unsigned int t;
    if (rs->bit_supply_bits < 10)
    {
        // stock up on bits
        int x = rs->x = (rs->x + 1) & 0xff;
        rs->r[x] += rs->r[(x + 58) & 0xff] + rs->r[(x + 119) & 0xff] + rs->r[(x + 178) & 0xff];
        rs->bit_supply |= (uint64_t )rs->r[x] << rs->bit_supply_bits;
        rs->bit_supply_bits += 32;
    }
    t = rs->bit_supply & 1023; // next 10 bits
    rs->bit_supply >>= 10;
    rs->bit_supply_bits -= 10;
    return t;
}

static int drs_call (lua_State *L)
{
    int t, q, r;
    random_state *rs = ldrs_check_state (L, 1);
    int x = luaL_optinteger (L, 2, 12); // digits
    int e = luaL_optinteger (L, 3, -x); // exponent
    decNumber *dnr = ldn_make_decNumber (L); // push
    // check for maxdigits
    if (!(0 < x && x <= DECNUMDIGITS))
    {
        luaL_error (L, "decNumber random %d digits exceeds available %d digits", x, DECNUMDIGITS);
    }
    if (!(DEC_MIN_EMIN <= e && e <= DEC_MAX_EMAX))
    {
        luaL_error (L, "decNumber exponent %d exceeds available range", e);
    }
    // this gets into decNumber's pants for efficiency
#if DECDPUN != 3
#error "DECDPUN must be 3 for drs_call which assumes 10 bits and 0..999 per unit"
#endif
    q = x / DECDPUN;
    r = x - (q * DECDPUN);
    if (q > DECNUMUNITS || (q == DECNUMUNITS && r != 0))
    {
        luaL_error (L, "decNumber random %d digits failed with %d units", x, q);
    }
    dnr->digits = x;
    dnr->exponent = e;
    dnr->bits = 0;
    while (r != 0)
    {
        t = lfib4_10bits (rs);
        if (t < 1000)
        {
            // too many bits; what can you do?
            dnr->lsu[q] = t % (r == 1 ? 10 : 100);
            r = 0;
        }
        // else reject 1000..1023
    }
    while (q > 0)
    {
        t = lfib4_10bits (rs);
        if (t < 1000)
        {
            // append 3 digits
            dnr->lsu[--q] = t;
        }
        // else reject 1000..1023
    }
    return 1;
}

#endif // LDN_ENABLE_RANDOM

/* ************************ decNumber constants *********************** */

#define DEC_(s)  { #s, DEC_ ## s },

static const struct {
    const char* name;
................................................................................
    DEC_(INIT_DECIMAL64)
    DEC_(INIT_DECIMAL128)
    /* compile time config */
    {"MAX_DIGITS", DECNUMDIGITS },
    /* terminator */
    { NULL, 0 }
};

#if LDN_ENABLE_RANDOM
static const luaL_reg dn_drandom_meta_lib[] =
{
    { "__call",     drs_call  },
    { NULL,         NULL      }
};
#endif

static const luaL_reg dn_dnumber_meta_lib[] =
{
    {"eq",              dn_eq     },
    {"lt",              dn_lt     },
    {"le",              dn_le     },
    
................................................................................

    {"getcontext",      dn_get_context   },
    {"setcontext",      dn_set_context   },
    {"tonumber",        dn_todecnumber   },
    {"tostring",        dn_string        },
    {"toengstring",     dn_engstring     },
    
    {"randomstate",     dn_randomstate   },
    
#if LDN_CACHE_TEST
    {"cachestats",      dn_cache_stats   },
#endif
    {NULL, NULL}
};

static void mkmeta (lua_State *L, const char *uname, const char *tname, const luaL_reg *reg)
{
    lua_pushstring (L, uname);    /* accesible for user with this name */
    luaL_newmetatable (L, tname); /* internal checkudata name */
    luaL_register (L, NULL, reg); /* register metatable functions */
    lua_pushstring (L, "__index");
    lua_pushvalue (L, -2);       /* push metatable */
    lua_rawset (L, -3);          /* metatable.__index = metatable */
    lua_settable (L,-3);
}

LUALIB_API int luaopen_ldecNumber(lua_State *L)
{
    /* initialize constants */
    dn_dnc_init ();
    /* create a shared environment for the decNumber functions */
    lua_createtable (L, 0, 5);
................................................................................
            i += 1;
        }
    }
    lua_pushliteral (L,"version");              /** version */
    lua_pushliteral (L, DN_VERSION);
    lua_settable (L, -3);
    /* */
#if LDN_ENABLE_RANDOM
    mkmeta (L, "drandom_metatable", dn_drandom_meta, dn_drandom_meta_lib);
#endif
    /* */
    mkmeta (L, "context_metatable", dn_context_meta, dn_context_meta_lib);




    /* */








    mkmeta (L, "number_metatable", dn_dnumber_meta, dn_dnumber_meta_lib);
    /* */
#if LDN_SEAL_TABLES
    /* set decNumber's metatable to itself - set as readonly (__newindex) */
    lua_pushvalue(L, -1);
    lua_setmetatable(L, -2);
#endif
    return 1;
}

/* end of ldecNumber.c */

Added test/ldecNumberGausstest.lua.





































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

require "ldecNumber"

require "ldislin"

local sigma = arg[1] or 12
local trials = arg[2] or 100000

local use_qbars = false

local floor = math.floor

print (decNumber.version)

print (dislin.version)

local function D (s) return decNumber.tonumber (s) end

local D1 = D"1"
local D2 = D"2"
local Dm2 = D"-2"

local r = decNumber.randomstate()

local function gaussian (sigma)
  local x1 = r(12) * D2 - D1
  local x2 = r(12) * D2 - D1
  local r2 = x1 * x1 + x2 * x2
  if r2:iszero() or r2 > D1
  then return gaussian (sigma) -- loop
  else
    local m = (Dm2 * r2:ln() / r2):squareroot() * sigma
    return x1 * m, x2 * m
  end
end

local t = {}

if use_qbars then

for i = 1,trials do
    local x1, x2 = gaussian(sigma)
    local function tally (x) 
        local n = tonumber(x:floor(D1):tostring()) + (sigma*5)
        t[n] = (t[n] or 0) + 1
    end
    tally (x1)
    tally (x2)
end

for i = 1,#t do
    t[i] = (t[i] or 0)
    print (t[i])
end

dislin.metafl ('cons')
dislin.disini ()
dislin.labdig (0,'bars')
dislin.labpos ('inside','bars')
dislin.qplbar (t,#t)

else

for i = 1,trials do
    local x1, x2 = gaussian(sigma)
    local function tally (x) 
        local n = tonumber(x:floor(D1):tostring())
        table.insert (t,n)
    end
    tally (x1)
    tally (x2)
end

local x,y,n = dislin.histog (t, #t)

dislin.metafl ('cons')
dislin.disini ()
--dislin.polcrv ('STEP')
dislin.polcrv ('BARS')
dislin.qplot (x,y,n)

end

Changes to test/ldecNumberUnitTest.lua.

508
509
510
511
512
513
514
515


















516
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setcontext()
end



















lunit.run()








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setcontext()
end

local rng_funcs = lunit.TestCase("Random Numbers")

function rng_funcs:test()
    local r = decNumber.randomstate(999,777,555)
    local s = decNumber.randomstate(999,777,555)
    local t = decNumber.randomstate()
    local r1,s1,t1 = r(), s(), t()
    local r2,s2,t2 = r(), s(), t()
    assert_equal (r1, s1)
    assert_not_equal (r1,t1)
    assert_equal (r2, s2)
    assert_not_equal (r1,r2)
    assert_not_equal (r2,t2)
    assert_true(r(12,-12) < r(12,1))
    assert_true(t(12,-12) < decNumber.tonumber "1")
    assert_true(t(12,1) > decNumber.tonumber "1")
end

lunit.run()