decimal 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2350 @@
1
+ /*
2
+ * Ruby's Integer part from ruby_2_0_0, r47627.
3
+ *
4
+ * These are hand copies (with few modifications) taken from original
5
+ * Ruby's code in "numeric.c" and "bignum.c," so the copyrights are
6
+ * held by matz and other contributors:
7
+ *
8
+ * Copyright (C) 1993-2014 Yukihiro Matsumoto
9
+ *
10
+ */
11
+
12
+ /*
13
+ * copied from internal.h
14
+ */
15
+
16
+ #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
17
+ (a) == 0 ? 0 : \
18
+ (a) == -1 ? (b) < -(max) : \
19
+ (a) > 0 ? \
20
+ ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
21
+ ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
22
+ #define MUL_OVERFLOW_FIXNUM_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
23
+
24
+ /*
25
+ * copied from util.c
26
+ */
27
+
28
+ #include <errno.h>
29
+
30
+ #ifdef WORDS_BIGENDIAN
31
+ #define IEEE_BIG_ENDIAN
32
+ #else
33
+ #define IEEE_LITTLE_ENDIAN
34
+ #endif
35
+
36
+ #ifdef __vax__
37
+ #define VAX
38
+ #undef IEEE_BIG_ENDIAN
39
+ #undef IEEE_LITTLE_ENDIAN
40
+ #endif
41
+
42
+ #if defined(__arm__) && !defined(__VFP_FP__)
43
+ #define IEEE_BIG_ENDIAN
44
+ #undef IEEE_LITTLE_ENDIAN
45
+ #endif
46
+
47
+ #undef Long
48
+ #undef ULong
49
+
50
+ #if SIZEOF_INT == 4
51
+ #define Long int
52
+ #define ULong unsigned int
53
+ #elif SIZEOF_LONG == 4
54
+ #define Long long int
55
+ #define ULong unsigned long int
56
+ #endif
57
+
58
+ #if HAVE_LONG_LONG
59
+ #define Llong LONG_LONG
60
+ #endif
61
+
62
+ #ifdef DEBUG
63
+ #include "stdio.h"
64
+ #define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
65
+ #endif
66
+
67
+ #include "stdlib.h"
68
+ #include "string.h"
69
+
70
+ #ifdef USE_LOCALE
71
+ #include "locale.h"
72
+ #endif
73
+
74
+ #ifdef MALLOC
75
+ extern void *MALLOC(size_t);
76
+ #else
77
+ #define MALLOC malloc
78
+ #endif
79
+ #ifdef FREE
80
+ extern void FREE(void*);
81
+ #else
82
+ #define FREE free
83
+ #endif
84
+
85
+ #ifndef Omit_Private_Memory
86
+ #ifndef PRIVATE_MEM
87
+ #define PRIVATE_MEM 2304
88
+ #endif
89
+ #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
90
+ static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
91
+ #endif
92
+
93
+ #undef IEEE_Arith
94
+ #undef Avoid_Underflow
95
+ #ifdef IEEE_BIG_ENDIAN
96
+ #define IEEE_Arith
97
+ #endif
98
+ #ifdef IEEE_LITTLE_ENDIAN
99
+ #define IEEE_Arith
100
+ #endif
101
+
102
+ #ifdef Bad_float_h
103
+
104
+ #ifdef IEEE_Arith
105
+ #define DBL_DIG 15
106
+ #define DBL_MAX_10_EXP 308
107
+ #define DBL_MAX_EXP 1024
108
+ #define FLT_RADIX 2
109
+ #endif /*IEEE_Arith*/
110
+
111
+ #ifdef IBM
112
+ #define DBL_DIG 16
113
+ #define DBL_MAX_10_EXP 75
114
+ #define DBL_MAX_EXP 63
115
+ #define FLT_RADIX 16
116
+ #define DBL_MAX 7.2370055773322621e+75
117
+ #endif
118
+
119
+ #ifdef VAX
120
+ #define DBL_DIG 16
121
+ #define DBL_MAX_10_EXP 38
122
+ #define DBL_MAX_EXP 127
123
+ #define FLT_RADIX 2
124
+ #define DBL_MAX 1.7014118346046923e+38
125
+ #endif
126
+
127
+ #ifndef LONG_MAX
128
+ #define LONG_MAX 2147483647
129
+ #endif
130
+
131
+ #else /* ifndef Bad_float_h */
132
+ #include "float.h"
133
+ #endif /* Bad_float_h */
134
+
135
+ #ifndef __MATH_H__
136
+ #include "math.h"
137
+ #endif
138
+
139
+ #ifdef __cplusplus
140
+ extern "C" {
141
+ #if 0
142
+ } /* satisfy cc-mode */
143
+ #endif
144
+ #endif
145
+
146
+ #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
147
+ Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
148
+ #endif
149
+
150
+ typedef union { double d; ULong L[2]; } U;
151
+
152
+ #ifdef YES_ALIAS
153
+ typedef double double_u;
154
+ # define dval(x) (x)
155
+ # ifdef IEEE_LITTLE_ENDIAN
156
+ # define word0(x) (((ULong *)&(x))[1])
157
+ # define word1(x) (((ULong *)&(x))[0])
158
+ # else
159
+ # define word0(x) (((ULong *)&(x))[0])
160
+ # define word1(x) (((ULong *)&(x))[1])
161
+ # endif
162
+ #else
163
+ typedef U double_u;
164
+ # ifdef IEEE_LITTLE_ENDIAN
165
+ # define word0(x) ((x).L[1])
166
+ # define word1(x) ((x).L[0])
167
+ # else
168
+ # define word0(x) ((x).L[0])
169
+ # define word1(x) ((x).L[1])
170
+ # endif
171
+ # define dval(x) ((x).d)
172
+ #endif
173
+
174
+ /* The following definition of Storeinc is appropriate for MIPS processors.
175
+ * An alternative that might be better on some machines is
176
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
177
+ */
178
+ #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
179
+ #define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \
180
+ ((unsigned short *)(a))[0] = (unsigned short)(c), (a)++)
181
+ #else
182
+ #define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \
183
+ ((unsigned short *)(a))[1] = (unsigned short)(c), (a)++)
184
+ #endif
185
+
186
+ /* #define P DBL_MANT_DIG */
187
+ /* Ten_pmax = floor(P*log(2)/log(5)) */
188
+ /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
189
+ /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
190
+ /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
191
+
192
+ #ifdef IEEE_Arith
193
+ #define Exp_shift 20
194
+ #define Exp_shift1 20
195
+ #define Exp_msk1 0x100000
196
+ #define Exp_msk11 0x100000
197
+ #define Exp_mask 0x7ff00000
198
+ #define P 53
199
+ #define Bias 1023
200
+ #define Emin (-1022)
201
+ #define Exp_1 0x3ff00000
202
+ #define Exp_11 0x3ff00000
203
+ #define Ebits 11
204
+ #define Frac_mask 0xfffff
205
+ #define Frac_mask1 0xfffff
206
+ #define Ten_pmax 22
207
+ #define Bletch 0x10
208
+ #define Bndry_mask 0xfffff
209
+ #define Bndry_mask1 0xfffff
210
+ #define LSB 1
211
+ #define Sign_bit 0x80000000
212
+ #define Log2P 1
213
+ #define Tiny0 0
214
+ #define Tiny1 1
215
+ #define Quick_max 14
216
+ #define Int_max 14
217
+ #ifndef NO_IEEE_Scale
218
+ #define Avoid_Underflow
219
+ #ifdef Flush_Denorm /* debugging option */
220
+ #undef Sudden_Underflow
221
+ #endif
222
+ #endif
223
+
224
+ #ifndef Flt_Rounds
225
+ #ifdef FLT_ROUNDS
226
+ #define Flt_Rounds FLT_ROUNDS
227
+ #else
228
+ #define Flt_Rounds 1
229
+ #endif
230
+ #endif /*Flt_Rounds*/
231
+
232
+ #ifdef Honor_FLT_ROUNDS
233
+ #define Rounding rounding
234
+ #undef Check_FLT_ROUNDS
235
+ #define Check_FLT_ROUNDS
236
+ #else
237
+ #define Rounding Flt_Rounds
238
+ #endif
239
+
240
+ #else /* ifndef IEEE_Arith */
241
+ #undef Check_FLT_ROUNDS
242
+ #undef Honor_FLT_ROUNDS
243
+ #undef SET_INEXACT
244
+ #undef Sudden_Underflow
245
+ #define Sudden_Underflow
246
+ #ifdef IBM
247
+ #undef Flt_Rounds
248
+ #define Flt_Rounds 0
249
+ #define Exp_shift 24
250
+ #define Exp_shift1 24
251
+ #define Exp_msk1 0x1000000
252
+ #define Exp_msk11 0x1000000
253
+ #define Exp_mask 0x7f000000
254
+ #define P 14
255
+ #define Bias 65
256
+ #define Exp_1 0x41000000
257
+ #define Exp_11 0x41000000
258
+ #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
259
+ #define Frac_mask 0xffffff
260
+ #define Frac_mask1 0xffffff
261
+ #define Bletch 4
262
+ #define Ten_pmax 22
263
+ #define Bndry_mask 0xefffff
264
+ #define Bndry_mask1 0xffffff
265
+ #define LSB 1
266
+ #define Sign_bit 0x80000000
267
+ #define Log2P 4
268
+ #define Tiny0 0x100000
269
+ #define Tiny1 0
270
+ #define Quick_max 14
271
+ #define Int_max 15
272
+ #else /* VAX */
273
+ #undef Flt_Rounds
274
+ #define Flt_Rounds 1
275
+ #define Exp_shift 23
276
+ #define Exp_shift1 7
277
+ #define Exp_msk1 0x80
278
+ #define Exp_msk11 0x800000
279
+ #define Exp_mask 0x7f80
280
+ #define P 56
281
+ #define Bias 129
282
+ #define Exp_1 0x40800000
283
+ #define Exp_11 0x4080
284
+ #define Ebits 8
285
+ #define Frac_mask 0x7fffff
286
+ #define Frac_mask1 0xffff007f
287
+ #define Ten_pmax 24
288
+ #define Bletch 2
289
+ #define Bndry_mask 0xffff007f
290
+ #define Bndry_mask1 0xffff007f
291
+ #define LSB 0x10000
292
+ #define Sign_bit 0x8000
293
+ #define Log2P 1
294
+ #define Tiny0 0x80
295
+ #define Tiny1 0
296
+ #define Quick_max 15
297
+ #define Int_max 15
298
+ #endif /* IBM, VAX */
299
+ #endif /* IEEE_Arith */
300
+
301
+ #ifndef IEEE_Arith
302
+ #define ROUND_BIASED
303
+ #endif
304
+
305
+ #ifdef RND_PRODQUOT
306
+ #define rounded_product(a,b) ((a) = rnd_prod((a), (b)))
307
+ #define rounded_quotient(a,b) ((a) = rnd_quot((a), (b)))
308
+ extern double rnd_prod(double, double), rnd_quot(double, double);
309
+ #else
310
+ #define rounded_product(a,b) ((a) *= (b))
311
+ #define rounded_quotient(a,b) ((a) /= (b))
312
+ #endif
313
+
314
+ #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
315
+ #define Big1 0xffffffff
316
+
317
+ #ifndef Pack_32
318
+ #define Pack_32
319
+ #endif
320
+
321
+ #define FFFFFFFF 0xffffffffUL
322
+
323
+ #ifdef NO_LONG_LONG
324
+ #undef ULLong
325
+ #ifdef Just_16
326
+ #undef Pack_32
327
+ /* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
328
+ * This makes some inner loops simpler and sometimes saves work
329
+ * during multiplications, but it often seems to make things slightly
330
+ * slower. Hence the default is now to store 32 bits per Long.
331
+ */
332
+ #endif
333
+ #else /* long long available */
334
+ #ifndef Llong
335
+ #define Llong long long
336
+ #endif
337
+ #ifndef ULLong
338
+ #define ULLong unsigned Llong
339
+ #endif
340
+ #endif /* NO_LONG_LONG */
341
+
342
+ #define MULTIPLE_THREADS 1
343
+
344
+ #ifndef MULTIPLE_THREADS
345
+ #define ACQUIRE_DTOA_LOCK(n) /*nothing*/
346
+ #define FREE_DTOA_LOCK(n) /*nothing*/
347
+ #else
348
+ #define ACQUIRE_DTOA_LOCK(n) /*unused right now*/
349
+ #define FREE_DTOA_LOCK(n) /*unused right now*/
350
+ #endif
351
+
352
+ #define Kmax 15
353
+
354
+ struct Bigint {
355
+ struct Bigint *next;
356
+ int k, maxwds, sign, wds;
357
+ ULong x[1];
358
+ };
359
+
360
+ typedef struct Bigint Bigint;
361
+
362
+ static Bigint *freelist[Kmax+1];
363
+
364
+ static Bigint *
365
+ Balloc(int k)
366
+ {
367
+ int x;
368
+ Bigint *rv;
369
+ #ifndef Omit_Private_Memory
370
+ size_t len;
371
+ #endif
372
+
373
+ ACQUIRE_DTOA_LOCK(0);
374
+ if (k <= Kmax && (rv = freelist[k]) != 0) {
375
+ freelist[k] = rv->next;
376
+ }
377
+ else {
378
+ x = 1 << k;
379
+ #ifdef Omit_Private_Memory
380
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
381
+ #else
382
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
383
+ /sizeof(double);
384
+ if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
385
+ rv = (Bigint*)pmem_next;
386
+ pmem_next += len;
387
+ }
388
+ else
389
+ rv = (Bigint*)MALLOC(len*sizeof(double));
390
+ #endif
391
+ rv->k = k;
392
+ rv->maxwds = x;
393
+ }
394
+ FREE_DTOA_LOCK(0);
395
+ rv->sign = rv->wds = 0;
396
+ return rv;
397
+ }
398
+
399
+ static void
400
+ Bfree(Bigint *v)
401
+ {
402
+ if (v) {
403
+ if (v->k > Kmax) {
404
+ FREE(v);
405
+ return;
406
+ }
407
+ ACQUIRE_DTOA_LOCK(0);
408
+ v->next = freelist[v->k];
409
+ freelist[v->k] = v;
410
+ FREE_DTOA_LOCK(0);
411
+ }
412
+ }
413
+
414
+ #define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
415
+ (y)->wds*sizeof(Long) + 2*sizeof(int))
416
+
417
+ static Bigint *
418
+ multadd(Bigint *b, int m, int a) /* multiply by m and add a */
419
+ {
420
+ int i, wds;
421
+ ULong *x;
422
+ #ifdef ULLong
423
+ ULLong carry, y;
424
+ #else
425
+ ULong carry, y;
426
+ #ifdef Pack_32
427
+ ULong xi, z;
428
+ #endif
429
+ #endif
430
+ Bigint *b1;
431
+
432
+ wds = b->wds;
433
+ x = b->x;
434
+ i = 0;
435
+ carry = a;
436
+ do {
437
+ #ifdef ULLong
438
+ y = *x * (ULLong)m + carry;
439
+ carry = y >> 32;
440
+ *x++ = (ULong)(y & FFFFFFFF);
441
+ #else
442
+ #ifdef Pack_32
443
+ xi = *x;
444
+ y = (xi & 0xffff) * m + carry;
445
+ z = (xi >> 16) * m + (y >> 16);
446
+ carry = z >> 16;
447
+ *x++ = (z << 16) + (y & 0xffff);
448
+ #else
449
+ y = *x * m + carry;
450
+ carry = y >> 16;
451
+ *x++ = y & 0xffff;
452
+ #endif
453
+ #endif
454
+ } while (++i < wds);
455
+ if (carry) {
456
+ if (wds >= b->maxwds) {
457
+ b1 = Balloc(b->k+1);
458
+ Bcopy(b1, b);
459
+ Bfree(b);
460
+ b = b1;
461
+ }
462
+ b->x[wds++] = (ULong)carry;
463
+ b->wds = wds;
464
+ }
465
+ return b;
466
+ }
467
+
468
+ /* removed: s2b() */
469
+
470
+ static int
471
+ hi0bits(register ULong x)
472
+ {
473
+ register int k = 0;
474
+
475
+ if (!(x & 0xffff0000)) {
476
+ k = 16;
477
+ x <<= 16;
478
+ }
479
+ if (!(x & 0xff000000)) {
480
+ k += 8;
481
+ x <<= 8;
482
+ }
483
+ if (!(x & 0xf0000000)) {
484
+ k += 4;
485
+ x <<= 4;
486
+ }
487
+ if (!(x & 0xc0000000)) {
488
+ k += 2;
489
+ x <<= 2;
490
+ }
491
+ if (!(x & 0x80000000)) {
492
+ k++;
493
+ if (!(x & 0x40000000))
494
+ return 32;
495
+ }
496
+ return k;
497
+ }
498
+
499
+ static int
500
+ lo0bits(ULong *y)
501
+ {
502
+ register int k;
503
+ register ULong x = *y;
504
+
505
+ if (x & 7) {
506
+ if (x & 1)
507
+ return 0;
508
+ if (x & 2) {
509
+ *y = x >> 1;
510
+ return 1;
511
+ }
512
+ *y = x >> 2;
513
+ return 2;
514
+ }
515
+ k = 0;
516
+ if (!(x & 0xffff)) {
517
+ k = 16;
518
+ x >>= 16;
519
+ }
520
+ if (!(x & 0xff)) {
521
+ k += 8;
522
+ x >>= 8;
523
+ }
524
+ if (!(x & 0xf)) {
525
+ k += 4;
526
+ x >>= 4;
527
+ }
528
+ if (!(x & 0x3)) {
529
+ k += 2;
530
+ x >>= 2;
531
+ }
532
+ if (!(x & 1)) {
533
+ k++;
534
+ x >>= 1;
535
+ if (!x)
536
+ return 32;
537
+ }
538
+ *y = x;
539
+ return k;
540
+ }
541
+
542
+ static Bigint *
543
+ i2b(int i)
544
+ {
545
+ Bigint *b;
546
+
547
+ b = Balloc(1);
548
+ b->x[0] = i;
549
+ b->wds = 1;
550
+ return b;
551
+ }
552
+
553
+ static Bigint *
554
+ mult(Bigint *a, Bigint *b)
555
+ {
556
+ Bigint *c;
557
+ int k, wa, wb, wc;
558
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
559
+ ULong y;
560
+ #ifdef ULLong
561
+ ULLong carry, z;
562
+ #else
563
+ ULong carry, z;
564
+ #ifdef Pack_32
565
+ ULong z2;
566
+ #endif
567
+ #endif
568
+
569
+ if (a->wds < b->wds) {
570
+ c = a;
571
+ a = b;
572
+ b = c;
573
+ }
574
+ k = a->k;
575
+ wa = a->wds;
576
+ wb = b->wds;
577
+ wc = wa + wb;
578
+ if (wc > a->maxwds)
579
+ k++;
580
+ c = Balloc(k);
581
+ for (x = c->x, xa = x + wc; x < xa; x++)
582
+ *x = 0;
583
+ xa = a->x;
584
+ xae = xa + wa;
585
+ xb = b->x;
586
+ xbe = xb + wb;
587
+ xc0 = c->x;
588
+ #ifdef ULLong
589
+ for (; xb < xbe; xc0++) {
590
+ if ((y = *xb++) != 0) {
591
+ x = xa;
592
+ xc = xc0;
593
+ carry = 0;
594
+ do {
595
+ z = *x++ * (ULLong)y + *xc + carry;
596
+ carry = z >> 32;
597
+ *xc++ = (ULong)(z & FFFFFFFF);
598
+ } while (x < xae);
599
+ *xc = (ULong)carry;
600
+ }
601
+ }
602
+ #else
603
+ #ifdef Pack_32
604
+ for (; xb < xbe; xb++, xc0++) {
605
+ if (y = *xb & 0xffff) {
606
+ x = xa;
607
+ xc = xc0;
608
+ carry = 0;
609
+ do {
610
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
611
+ carry = z >> 16;
612
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
613
+ carry = z2 >> 16;
614
+ Storeinc(xc, z2, z);
615
+ } while (x < xae);
616
+ *xc = (ULong)carry;
617
+ }
618
+ if (y = *xb >> 16) {
619
+ x = xa;
620
+ xc = xc0;
621
+ carry = 0;
622
+ z2 = *xc;
623
+ do {
624
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
625
+ carry = z >> 16;
626
+ Storeinc(xc, z, z2);
627
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
628
+ carry = z2 >> 16;
629
+ } while (x < xae);
630
+ *xc = z2;
631
+ }
632
+ }
633
+ #else
634
+ for (; xb < xbe; xc0++) {
635
+ if (y = *xb++) {
636
+ x = xa;
637
+ xc = xc0;
638
+ carry = 0;
639
+ do {
640
+ z = *x++ * y + *xc + carry;
641
+ carry = z >> 16;
642
+ *xc++ = z & 0xffff;
643
+ } while (x < xae);
644
+ *xc = (ULong)carry;
645
+ }
646
+ }
647
+ #endif
648
+ #endif
649
+ for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
650
+ c->wds = wc;
651
+ return c;
652
+ }
653
+
654
+ static Bigint *p5s;
655
+
656
+ static Bigint *
657
+ pow5mult(Bigint *b, int k)
658
+ {
659
+ Bigint *b1, *p5, *p51;
660
+ int i;
661
+ static int p05[3] = { 5, 25, 125 };
662
+
663
+ if ((i = k & 3) != 0)
664
+ b = multadd(b, p05[i-1], 0);
665
+
666
+ if (!(k >>= 2))
667
+ return b;
668
+ if (!(p5 = p5s)) {
669
+ /* first time */
670
+ #ifdef MULTIPLE_THREADS
671
+ ACQUIRE_DTOA_LOCK(1);
672
+ if (!(p5 = p5s)) {
673
+ p5 = p5s = i2b(625);
674
+ p5->next = 0;
675
+ }
676
+ FREE_DTOA_LOCK(1);
677
+ #else
678
+ p5 = p5s = i2b(625);
679
+ p5->next = 0;
680
+ #endif
681
+ }
682
+ for (;;) {
683
+ if (k & 1) {
684
+ b1 = mult(b, p5);
685
+ Bfree(b);
686
+ b = b1;
687
+ }
688
+ if (!(k >>= 1))
689
+ break;
690
+ if (!(p51 = p5->next)) {
691
+ #ifdef MULTIPLE_THREADS
692
+ ACQUIRE_DTOA_LOCK(1);
693
+ if (!(p51 = p5->next)) {
694
+ p51 = p5->next = mult(p5,p5);
695
+ p51->next = 0;
696
+ }
697
+ FREE_DTOA_LOCK(1);
698
+ #else
699
+ p51 = p5->next = mult(p5,p5);
700
+ p51->next = 0;
701
+ #endif
702
+ }
703
+ p5 = p51;
704
+ }
705
+ return b;
706
+ }
707
+
708
+ static Bigint *
709
+ lshift(Bigint *b, int k)
710
+ {
711
+ int i, k1, n, n1;
712
+ Bigint *b1;
713
+ ULong *x, *x1, *xe, z;
714
+
715
+ #ifdef Pack_32
716
+ n = k >> 5;
717
+ #else
718
+ n = k >> 4;
719
+ #endif
720
+ k1 = b->k;
721
+ n1 = n + b->wds + 1;
722
+ for (i = b->maxwds; n1 > i; i <<= 1)
723
+ k1++;
724
+ b1 = Balloc(k1);
725
+ x1 = b1->x;
726
+ for (i = 0; i < n; i++)
727
+ *x1++ = 0;
728
+ x = b->x;
729
+ xe = x + b->wds;
730
+ #ifdef Pack_32
731
+ if (k &= 0x1f) {
732
+ k1 = 32 - k;
733
+ z = 0;
734
+ do {
735
+ *x1++ = *x << k | z;
736
+ z = *x++ >> k1;
737
+ } while (x < xe);
738
+ if ((*x1 = z) != 0)
739
+ ++n1;
740
+ }
741
+ #else
742
+ if (k &= 0xf) {
743
+ k1 = 16 - k;
744
+ z = 0;
745
+ do {
746
+ *x1++ = *x << k & 0xffff | z;
747
+ z = *x++ >> k1;
748
+ } while (x < xe);
749
+ if (*x1 = z)
750
+ ++n1;
751
+ }
752
+ #endif
753
+ else
754
+ do {
755
+ *x1++ = *x++;
756
+ } while (x < xe);
757
+ b1->wds = n1 - 1;
758
+ Bfree(b);
759
+ return b1;
760
+ }
761
+
762
+ /* renamed from cmp() */
763
+ static int
764
+ bicmp(Bigint *a, Bigint *b)
765
+ {
766
+ ULong *xa, *xa0, *xb, *xb0;
767
+ int i, j;
768
+
769
+ i = a->wds;
770
+ j = b->wds;
771
+ #ifdef DEBUG
772
+ if (i > 1 && !a->x[i-1])
773
+ Bug("bicmp called with a->x[a->wds-1] == 0");
774
+ if (j > 1 && !b->x[j-1])
775
+ Bug("bicmp called with b->x[b->wds-1] == 0");
776
+ #endif
777
+ if (i -= j)
778
+ return i;
779
+ xa0 = a->x;
780
+ xa = xa0 + j;
781
+ xb0 = b->x;
782
+ xb = xb0 + j;
783
+ for (;;) {
784
+ if (*--xa != *--xb)
785
+ return *xa < *xb ? -1 : 1;
786
+ if (xa <= xa0)
787
+ break;
788
+ }
789
+ return 0;
790
+ }
791
+
792
+ static Bigint *
793
+ diff(Bigint *a, Bigint *b)
794
+ {
795
+ Bigint *c;
796
+ int i, wa, wb;
797
+ ULong *xa, *xae, *xb, *xbe, *xc;
798
+ #ifdef ULLong
799
+ ULLong borrow, y;
800
+ #else
801
+ ULong borrow, y;
802
+ #ifdef Pack_32
803
+ ULong z;
804
+ #endif
805
+ #endif
806
+
807
+ i = bicmp(a,b);
808
+ if (!i) {
809
+ c = Balloc(0);
810
+ c->wds = 1;
811
+ c->x[0] = 0;
812
+ return c;
813
+ }
814
+ if (i < 0) {
815
+ c = a;
816
+ a = b;
817
+ b = c;
818
+ i = 1;
819
+ }
820
+ else
821
+ i = 0;
822
+ c = Balloc(a->k);
823
+ c->sign = i;
824
+ wa = a->wds;
825
+ xa = a->x;
826
+ xae = xa + wa;
827
+ wb = b->wds;
828
+ xb = b->x;
829
+ xbe = xb + wb;
830
+ xc = c->x;
831
+ borrow = 0;
832
+ #ifdef ULLong
833
+ do {
834
+ y = (ULLong)*xa++ - *xb++ - borrow;
835
+ borrow = y >> 32 & (ULong)1;
836
+ *xc++ = (ULong)(y & FFFFFFFF);
837
+ } while (xb < xbe);
838
+ while (xa < xae) {
839
+ y = *xa++ - borrow;
840
+ borrow = y >> 32 & (ULong)1;
841
+ *xc++ = (ULong)(y & FFFFFFFF);
842
+ }
843
+ #else
844
+ #ifdef Pack_32
845
+ do {
846
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
847
+ borrow = (y & 0x10000) >> 16;
848
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
849
+ borrow = (z & 0x10000) >> 16;
850
+ Storeinc(xc, z, y);
851
+ } while (xb < xbe);
852
+ while (xa < xae) {
853
+ y = (*xa & 0xffff) - borrow;
854
+ borrow = (y & 0x10000) >> 16;
855
+ z = (*xa++ >> 16) - borrow;
856
+ borrow = (z & 0x10000) >> 16;
857
+ Storeinc(xc, z, y);
858
+ }
859
+ #else
860
+ do {
861
+ y = *xa++ - *xb++ - borrow;
862
+ borrow = (y & 0x10000) >> 16;
863
+ *xc++ = y & 0xffff;
864
+ } while (xb < xbe);
865
+ while (xa < xae) {
866
+ y = *xa++ - borrow;
867
+ borrow = (y & 0x10000) >> 16;
868
+ *xc++ = y & 0xffff;
869
+ }
870
+ #endif
871
+ #endif
872
+ while (!*--xc)
873
+ wa--;
874
+ c->wds = wa;
875
+ return c;
876
+ }
877
+
878
+ /* removed: ulp(), b2d() */
879
+
880
+ static Bigint *
881
+ d2b(double d_, int *e, int *bits)
882
+ {
883
+ double_u d;
884
+ Bigint *b;
885
+ int de, k;
886
+ ULong *x, y, z;
887
+ #ifndef Sudden_Underflow
888
+ int i;
889
+ #endif
890
+ #ifdef VAX
891
+ ULong d0, d1;
892
+ #endif
893
+ dval(d) = d_;
894
+ #ifdef VAX
895
+ d0 = word0(d) >> 16 | word0(d) << 16;
896
+ d1 = word1(d) >> 16 | word1(d) << 16;
897
+ #else
898
+ #define d0 word0(d)
899
+ #define d1 word1(d)
900
+ #endif
901
+
902
+ #ifdef Pack_32
903
+ b = Balloc(1);
904
+ #else
905
+ b = Balloc(2);
906
+ #endif
907
+ x = b->x;
908
+
909
+ z = d0 & Frac_mask;
910
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
911
+ #ifdef Sudden_Underflow
912
+ de = (int)(d0 >> Exp_shift);
913
+ #ifndef IBM
914
+ z |= Exp_msk11;
915
+ #endif
916
+ #else
917
+ if ((de = (int)(d0 >> Exp_shift)) != 0)
918
+ z |= Exp_msk1;
919
+ #endif
920
+ #ifdef Pack_32
921
+ if ((y = d1) != 0) {
922
+ if ((k = lo0bits(&y)) != 0) {
923
+ x[0] = y | z << (32 - k);
924
+ z >>= k;
925
+ }
926
+ else
927
+ x[0] = y;
928
+ #ifndef Sudden_Underflow
929
+ i =
930
+ #endif
931
+ b->wds = (x[1] = z) ? 2 : 1;
932
+ }
933
+ else {
934
+ #ifdef DEBUG
935
+ if (!z)
936
+ Bug("Zero passed to d2b");
937
+ #endif
938
+ k = lo0bits(&z);
939
+ x[0] = z;
940
+ #ifndef Sudden_Underflow
941
+ i =
942
+ #endif
943
+ b->wds = 1;
944
+ k += 32;
945
+ }
946
+ #else
947
+ if (y = d1) {
948
+ if (k = lo0bits(&y))
949
+ if (k >= 16) {
950
+ x[0] = y | z << 32 - k & 0xffff;
951
+ x[1] = z >> k - 16 & 0xffff;
952
+ x[2] = z >> k;
953
+ i = 2;
954
+ }
955
+ else {
956
+ x[0] = y & 0xffff;
957
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
958
+ x[2] = z >> k & 0xffff;
959
+ x[3] = z >> k+16;
960
+ i = 3;
961
+ }
962
+ else {
963
+ x[0] = y & 0xffff;
964
+ x[1] = y >> 16;
965
+ x[2] = z & 0xffff;
966
+ x[3] = z >> 16;
967
+ i = 3;
968
+ }
969
+ }
970
+ else {
971
+ #ifdef DEBUG
972
+ if (!z)
973
+ Bug("Zero passed to d2b");
974
+ #endif
975
+ k = lo0bits(&z);
976
+ if (k >= 16) {
977
+ x[0] = z;
978
+ i = 0;
979
+ }
980
+ else {
981
+ x[0] = z & 0xffff;
982
+ x[1] = z >> 16;
983
+ i = 1;
984
+ }
985
+ k += 32;
986
+ }
987
+ while (!x[i])
988
+ --i;
989
+ b->wds = i + 1;
990
+ #endif
991
+ #ifndef Sudden_Underflow
992
+ if (de) {
993
+ #endif
994
+ #ifdef IBM
995
+ *e = (de - Bias - (P-1) << 2) + k;
996
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
997
+ #else
998
+ *e = de - Bias - (P-1) + k;
999
+ *bits = P - k;
1000
+ #endif
1001
+ #ifndef Sudden_Underflow
1002
+ }
1003
+ else {
1004
+ *e = de - Bias - (P-1) + 1 + k;
1005
+ #ifdef Pack_32
1006
+ *bits = 32*i - hi0bits(x[i-1]);
1007
+ #else
1008
+ *bits = (i+2)*16 - hi0bits(x[i]);
1009
+ #endif
1010
+ }
1011
+ #endif
1012
+ return b;
1013
+ }
1014
+ #undef d0
1015
+ #undef d1
1016
+
1017
+ /* removed: ratio() */
1018
+
1019
+ static const double
1020
+ tens[] = {
1021
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1022
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1023
+ 1e20, 1e21, 1e22
1024
+ #ifdef VAX
1025
+ , 1e23, 1e24
1026
+ #endif
1027
+ };
1028
+
1029
+ static const double
1030
+ #ifdef IEEE_Arith
1031
+ bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1032
+ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
1033
+ #ifdef Avoid_Underflow
1034
+ 9007199254740992.*9007199254740992.e-256
1035
+ /* = 2^106 * 1e-53 */
1036
+ #else
1037
+ 1e-256
1038
+ #endif
1039
+ };
1040
+ /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
1041
+ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
1042
+ #define Scale_Bit 0x10
1043
+ #define n_bigtens 5
1044
+ #else
1045
+ #ifdef IBM
1046
+ bigtens[] = { 1e16, 1e32, 1e64 };
1047
+ static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1048
+ #define n_bigtens 3
1049
+ #else
1050
+ bigtens[] = { 1e16, 1e32 };
1051
+ static const double tinytens[] = { 1e-16, 1e-32 };
1052
+ #define n_bigtens 2
1053
+ #endif
1054
+ #endif
1055
+
1056
+ #ifndef IEEE_Arith
1057
+ #undef INFNAN_CHECK
1058
+ #endif
1059
+
1060
+ #ifdef INFNAN_CHECK
1061
+
1062
+ #ifndef NAN_WORD0
1063
+ #define NAN_WORD0 0x7ff80000
1064
+ #endif
1065
+
1066
+ #ifndef NAN_WORD1
1067
+ #define NAN_WORD1 0
1068
+ #endif
1069
+
1070
+ static int
1071
+ match(const char **sp, char *t)
1072
+ {
1073
+ int c, d;
1074
+ const char *s = *sp;
1075
+
1076
+ while (d = *t++) {
1077
+ if ((c = *++s) >= 'A' && c <= 'Z')
1078
+ c += 'a' - 'A';
1079
+ if (c != d)
1080
+ return 0;
1081
+ }
1082
+ *sp = s + 1;
1083
+ return 1;
1084
+ }
1085
+
1086
+ #ifndef No_Hex_NaN
1087
+ static void
1088
+ hexnan(double *rvp, const char **sp)
1089
+ {
1090
+ ULong c, x[2];
1091
+ const char *s;
1092
+ int havedig, udx0, xshift;
1093
+
1094
+ x[0] = x[1] = 0;
1095
+ havedig = xshift = 0;
1096
+ udx0 = 1;
1097
+ s = *sp;
1098
+ while (c = *(const unsigned char*)++s) {
1099
+ if (c >= '0' && c <= '9')
1100
+ c -= '0';
1101
+ else if (c >= 'a' && c <= 'f')
1102
+ c += 10 - 'a';
1103
+ else if (c >= 'A' && c <= 'F')
1104
+ c += 10 - 'A';
1105
+ else if (c <= ' ') {
1106
+ if (udx0 && havedig) {
1107
+ udx0 = 0;
1108
+ xshift = 1;
1109
+ }
1110
+ continue;
1111
+ }
1112
+ else if (/*(*/ c == ')' && havedig) {
1113
+ *sp = s + 1;
1114
+ break;
1115
+ }
1116
+ else
1117
+ return; /* invalid form: don't change *sp */
1118
+ havedig = 1;
1119
+ if (xshift) {
1120
+ xshift = 0;
1121
+ x[0] = x[1];
1122
+ x[1] = 0;
1123
+ }
1124
+ if (udx0)
1125
+ x[0] = (x[0] << 4) | (x[1] >> 28);
1126
+ x[1] = (x[1] << 4) | c;
1127
+ }
1128
+ if ((x[0] &= 0xfffff) || x[1]) {
1129
+ word0(*rvp) = Exp_mask | x[0];
1130
+ word1(*rvp) = x[1];
1131
+ }
1132
+ }
1133
+ #endif /*No_Hex_NaN*/
1134
+ #endif /* INFNAN_CHECK */
1135
+
1136
+ /* removed: ruby_strtod() */
1137
+
1138
+ static int
1139
+ quorem(Bigint *b, Bigint *S)
1140
+ {
1141
+ int n;
1142
+ ULong *bx, *bxe, q, *sx, *sxe;
1143
+ #ifdef ULLong
1144
+ ULLong borrow, carry, y, ys;
1145
+ #else
1146
+ ULong borrow, carry, y, ys;
1147
+ #ifdef Pack_32
1148
+ ULong si, z, zs;
1149
+ #endif
1150
+ #endif
1151
+
1152
+ n = S->wds;
1153
+ #ifdef DEBUG
1154
+ /*debug*/ if (b->wds > n)
1155
+ /*debug*/ Bug("oversize b in quorem");
1156
+ #endif
1157
+ if (b->wds < n)
1158
+ return 0;
1159
+ sx = S->x;
1160
+ sxe = sx + --n;
1161
+ bx = b->x;
1162
+ bxe = bx + n;
1163
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1164
+ #ifdef DEBUG
1165
+ /*debug*/ if (q > 9)
1166
+ /*debug*/ Bug("oversized quotient in quorem");
1167
+ #endif
1168
+ if (q) {
1169
+ borrow = 0;
1170
+ carry = 0;
1171
+ do {
1172
+ #ifdef ULLong
1173
+ ys = *sx++ * (ULLong)q + carry;
1174
+ carry = ys >> 32;
1175
+ y = *bx - (ys & FFFFFFFF) - borrow;
1176
+ borrow = y >> 32 & (ULong)1;
1177
+ *bx++ = (ULong)(y & FFFFFFFF);
1178
+ #else
1179
+ #ifdef Pack_32
1180
+ si = *sx++;
1181
+ ys = (si & 0xffff) * q + carry;
1182
+ zs = (si >> 16) * q + (ys >> 16);
1183
+ carry = zs >> 16;
1184
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
1185
+ borrow = (y & 0x10000) >> 16;
1186
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
1187
+ borrow = (z & 0x10000) >> 16;
1188
+ Storeinc(bx, z, y);
1189
+ #else
1190
+ ys = *sx++ * q + carry;
1191
+ carry = ys >> 16;
1192
+ y = *bx - (ys & 0xffff) - borrow;
1193
+ borrow = (y & 0x10000) >> 16;
1194
+ *bx++ = y & 0xffff;
1195
+ #endif
1196
+ #endif
1197
+ } while (sx <= sxe);
1198
+ if (!*bxe) {
1199
+ bx = b->x;
1200
+ while (--bxe > bx && !*bxe)
1201
+ --n;
1202
+ b->wds = n;
1203
+ }
1204
+ }
1205
+ if (bicmp(b, S) >= 0) {
1206
+ q++;
1207
+ borrow = 0;
1208
+ carry = 0;
1209
+ bx = b->x;
1210
+ sx = S->x;
1211
+ do {
1212
+ #ifdef ULLong
1213
+ ys = *sx++ + carry;
1214
+ carry = ys >> 32;
1215
+ y = *bx - (ys & FFFFFFFF) - borrow;
1216
+ borrow = y >> 32 & (ULong)1;
1217
+ *bx++ = (ULong)(y & FFFFFFFF);
1218
+ #else
1219
+ #ifdef Pack_32
1220
+ si = *sx++;
1221
+ ys = (si & 0xffff) + carry;
1222
+ zs = (si >> 16) + (ys >> 16);
1223
+ carry = zs >> 16;
1224
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
1225
+ borrow = (y & 0x10000) >> 16;
1226
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
1227
+ borrow = (z & 0x10000) >> 16;
1228
+ Storeinc(bx, z, y);
1229
+ #else
1230
+ ys = *sx++ + carry;
1231
+ carry = ys >> 16;
1232
+ y = *bx - (ys & 0xffff) - borrow;
1233
+ borrow = (y & 0x10000) >> 16;
1234
+ *bx++ = y & 0xffff;
1235
+ #endif
1236
+ #endif
1237
+ } while (sx <= sxe);
1238
+ bx = b->x;
1239
+ bxe = bx + n;
1240
+ if (!*bxe) {
1241
+ while (--bxe > bx && !*bxe)
1242
+ --n;
1243
+ b->wds = n;
1244
+ }
1245
+ }
1246
+ return q;
1247
+ }
1248
+
1249
+ #ifndef MULTIPLE_THREADS
1250
+ static char *dtoa_result;
1251
+ #endif
1252
+
1253
+ #ifndef MULTIPLE_THREADS
1254
+ static char *
1255
+ rv_alloc(int i)
1256
+ {
1257
+ return dtoa_result = xmalloc(i);
1258
+ }
1259
+ #else
1260
+ #define rv_alloc(i) xmalloc(i)
1261
+ #endif
1262
+
1263
+ static char *
1264
+ nrv_alloc(const char *s, char **rve, size_t n)
1265
+ {
1266
+ char *rv, *t;
1267
+
1268
+ t = rv = rv_alloc(n);
1269
+ while ((*t = *s++) != 0) t++;
1270
+ if (rve)
1271
+ *rve = t;
1272
+ return rv;
1273
+ }
1274
+
1275
+ #define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1)
1276
+
1277
+ #ifndef MULTIPLE_THREADS
1278
+ /* freedtoa(s) must be used to free values s returned by dtoa
1279
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
1280
+ * but for consistency with earlier versions of dtoa, it is optional
1281
+ * when MULTIPLE_THREADS is not defined.
1282
+ */
1283
+
1284
+ static void
1285
+ freedtoa(char *s)
1286
+ {
1287
+ xfree(s);
1288
+ }
1289
+ #endif
1290
+
1291
+ static const char INFSTR[] = "Infinity";
1292
+ static const char NANSTR[] = "NaN";
1293
+ static const char ZEROSTR[] = "0";
1294
+
1295
+ /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
1296
+ *
1297
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
1298
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
1299
+ *
1300
+ * Modifications:
1301
+ * 1. Rather than iterating, we use a simple numeric overestimate
1302
+ * to determine k = floor(log10(d)). We scale relevant
1303
+ * quantities using O(log2(k)) rather than O(k) multiplications.
1304
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
1305
+ * try to generate digits strictly left to right. Instead, we
1306
+ * compute with fewer bits and propagate the carry if necessary
1307
+ * when rounding the final digit up. This is often faster.
1308
+ * 3. Under the assumption that input will be rounded nearest,
1309
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
1310
+ * That is, we allow equality in stopping tests when the
1311
+ * round-nearest rule will give the same floating-point value
1312
+ * as would satisfaction of the stopping test with strict
1313
+ * inequality.
1314
+ * 4. We remove common factors of powers of 2 from relevant
1315
+ * quantities.
1316
+ * 5. When converting floating-point integers less than 1e16,
1317
+ * we use floating-point arithmetic rather than resorting
1318
+ * to multiple-precision integers.
1319
+ * 6. When asked to produce fewer than 15 digits, we first try
1320
+ * to get by with floating-point arithmetic; we resort to
1321
+ * multiple-precision integer arithmetic only if we cannot
1322
+ * guarantee that the floating-point calculation has given
1323
+ * the correctly rounded result. For k requested digits and
1324
+ * "uniformly" distributed input, the probability is
1325
+ * something like 10^(k-15) that we must resort to the Long
1326
+ * calculation.
1327
+ */
1328
+
1329
+ char *
1330
+ ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
1331
+ {
1332
+ /* Arguments ndigits, decpt, sign are similar to those
1333
+ of ecvt and fcvt; trailing zeros are suppressed from
1334
+ the returned string. If not null, *rve is set to point
1335
+ to the end of the return value. If d is +-Infinity or NaN,
1336
+ then *decpt is set to 9999.
1337
+
1338
+ mode:
1339
+ 0 ==> shortest string that yields d when read in
1340
+ and rounded to nearest.
1341
+ 1 ==> like 0, but with Steele & White stopping rule;
1342
+ e.g. with IEEE P754 arithmetic , mode 0 gives
1343
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
1344
+ 2 ==> max(1,ndigits) significant digits. This gives a
1345
+ return value similar to that of ecvt, except
1346
+ that trailing zeros are suppressed.
1347
+ 3 ==> through ndigits past the decimal point. This
1348
+ gives a return value similar to that from fcvt,
1349
+ except that trailing zeros are suppressed, and
1350
+ ndigits can be negative.
1351
+ 4,5 ==> similar to 2 and 3, respectively, but (in
1352
+ round-nearest mode) with the tests of mode 0 to
1353
+ possibly return a shorter string that rounds to d.
1354
+ With IEEE arithmetic and compilation with
1355
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
1356
+ as modes 2 and 3 when FLT_ROUNDS != 1.
1357
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
1358
+ fast floating-point estimate (if applicable).
1359
+
1360
+ Values of mode other than 0-9 are treated as mode 0.
1361
+
1362
+ Sufficient space is allocated to the return value
1363
+ to hold the suppressed trailing zeros.
1364
+ */
1365
+
1366
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1367
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1368
+ spec_case, try_quick;
1369
+ Long L;
1370
+ #ifndef Sudden_Underflow
1371
+ int denorm;
1372
+ ULong x;
1373
+ #endif
1374
+ Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
1375
+ double ds;
1376
+ double_u d, d2, eps;
1377
+ char *s, *s0;
1378
+ #ifdef Honor_FLT_ROUNDS
1379
+ int rounding;
1380
+ #endif
1381
+ #ifdef SET_INEXACT
1382
+ int inexact, oldinexact;
1383
+ #endif
1384
+
1385
+ dval(d) = d_;
1386
+
1387
+ #ifndef MULTIPLE_THREADS
1388
+ if (dtoa_result) {
1389
+ freedtoa(dtoa_result);
1390
+ dtoa_result = 0;
1391
+ }
1392
+ #endif
1393
+
1394
+ if (word0(d) & Sign_bit) {
1395
+ /* set sign for everything, including 0's and NaNs */
1396
+ *sign = 1;
1397
+ word0(d) &= ~Sign_bit; /* clear sign bit */
1398
+ }
1399
+ else
1400
+ *sign = 0;
1401
+
1402
+ #if defined(IEEE_Arith) + defined(VAX)
1403
+ #ifdef IEEE_Arith
1404
+ if ((word0(d) & Exp_mask) == Exp_mask)
1405
+ #else
1406
+ if (word0(d) == 0x8000)
1407
+ #endif
1408
+ {
1409
+ /* Infinity or NaN */
1410
+ *decpt = 9999;
1411
+ #ifdef IEEE_Arith
1412
+ if (!word1(d) && !(word0(d) & 0xfffff))
1413
+ return rv_strdup(INFSTR, rve);
1414
+ #endif
1415
+ return rv_strdup(NANSTR, rve);
1416
+ }
1417
+ #endif
1418
+ #ifdef IBM
1419
+ dval(d) += 0; /* normalize */
1420
+ #endif
1421
+ if (!dval(d)) {
1422
+ *decpt = 1;
1423
+ return rv_strdup(ZEROSTR, rve);
1424
+ }
1425
+
1426
+ #ifdef SET_INEXACT
1427
+ try_quick = oldinexact = get_inexact();
1428
+ inexact = 1;
1429
+ #endif
1430
+ #ifdef Honor_FLT_ROUNDS
1431
+ if ((rounding = Flt_Rounds) >= 2) {
1432
+ if (*sign)
1433
+ rounding = rounding == 2 ? 0 : 2;
1434
+ else
1435
+ if (rounding != 2)
1436
+ rounding = 0;
1437
+ }
1438
+ #endif
1439
+
1440
+ b = d2b(dval(d), &be, &bbits);
1441
+ #ifdef Sudden_Underflow
1442
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1443
+ #else
1444
+ if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
1445
+ #endif
1446
+ dval(d2) = dval(d);
1447
+ word0(d2) &= Frac_mask1;
1448
+ word0(d2) |= Exp_11;
1449
+ #ifdef IBM
1450
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
1451
+ dval(d2) /= 1 << j;
1452
+ #endif
1453
+
1454
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
1455
+ * log10(x) = log(x) / log(10)
1456
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
1457
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
1458
+ *
1459
+ * This suggests computing an approximation k to log10(d) by
1460
+ *
1461
+ * k = (i - Bias)*0.301029995663981
1462
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
1463
+ *
1464
+ * We want k to be too large rather than too small.
1465
+ * The error in the first-order Taylor series approximation
1466
+ * is in our favor, so we just round up the constant enough
1467
+ * to compensate for any error in the multiplication of
1468
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
1469
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
1470
+ * adding 1e-13 to the constant term more than suffices.
1471
+ * Hence we adjust the constant term to 0.1760912590558.
1472
+ * (We could get a more accurate k by invoking log10,
1473
+ * but this is probably not worthwhile.)
1474
+ */
1475
+
1476
+ i -= Bias;
1477
+ #ifdef IBM
1478
+ i <<= 2;
1479
+ i += j;
1480
+ #endif
1481
+ #ifndef Sudden_Underflow
1482
+ denorm = 0;
1483
+ }
1484
+ else {
1485
+ /* d is denormalized */
1486
+
1487
+ i = bbits + be + (Bias + (P-1) - 1);
1488
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
1489
+ : word1(d) << (32 - i);
1490
+ dval(d2) = x;
1491
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
1492
+ i -= (Bias + (P-1) - 1) + 1;
1493
+ denorm = 1;
1494
+ }
1495
+ #endif
1496
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
1497
+ k = (int)ds;
1498
+ if (ds < 0. && ds != k)
1499
+ k--; /* want k = floor(ds) */
1500
+ k_check = 1;
1501
+ if (k >= 0 && k <= Ten_pmax) {
1502
+ if (dval(d) < tens[k])
1503
+ k--;
1504
+ k_check = 0;
1505
+ }
1506
+ j = bbits - i - 1;
1507
+ if (j >= 0) {
1508
+ b2 = 0;
1509
+ s2 = j;
1510
+ }
1511
+ else {
1512
+ b2 = -j;
1513
+ s2 = 0;
1514
+ }
1515
+ if (k >= 0) {
1516
+ b5 = 0;
1517
+ s5 = k;
1518
+ s2 += k;
1519
+ }
1520
+ else {
1521
+ b2 -= k;
1522
+ b5 = -k;
1523
+ s5 = 0;
1524
+ }
1525
+ if (mode < 0 || mode > 9)
1526
+ mode = 0;
1527
+
1528
+ #ifndef SET_INEXACT
1529
+ #ifdef Check_FLT_ROUNDS
1530
+ try_quick = Rounding == 1;
1531
+ #else
1532
+ try_quick = 1;
1533
+ #endif
1534
+ #endif /*SET_INEXACT*/
1535
+
1536
+ if (mode > 5) {
1537
+ mode -= 4;
1538
+ try_quick = 0;
1539
+ }
1540
+ leftright = 1;
1541
+ ilim = ilim1 = -1;
1542
+ switch (mode) {
1543
+ case 0:
1544
+ case 1:
1545
+ i = 18;
1546
+ ndigits = 0;
1547
+ break;
1548
+ case 2:
1549
+ leftright = 0;
1550
+ /* no break */
1551
+ case 4:
1552
+ if (ndigits <= 0)
1553
+ ndigits = 1;
1554
+ ilim = ilim1 = i = ndigits;
1555
+ break;
1556
+ case 3:
1557
+ leftright = 0;
1558
+ /* no break */
1559
+ case 5:
1560
+ i = ndigits + k + 1;
1561
+ ilim = i;
1562
+ ilim1 = i - 1;
1563
+ if (i <= 0)
1564
+ i = 1;
1565
+ }
1566
+ s = s0 = rv_alloc(i+1);
1567
+
1568
+ #ifdef Honor_FLT_ROUNDS
1569
+ if (mode > 1 && rounding != 1)
1570
+ leftright = 0;
1571
+ #endif
1572
+
1573
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
1574
+
1575
+ /* Try to get by with floating-point arithmetic. */
1576
+
1577
+ i = 0;
1578
+ dval(d2) = dval(d);
1579
+ k0 = k;
1580
+ ilim0 = ilim;
1581
+ ieps = 2; /* conservative */
1582
+ if (k > 0) {
1583
+ ds = tens[k&0xf];
1584
+ j = k >> 4;
1585
+ if (j & Bletch) {
1586
+ /* prevent overflows */
1587
+ j &= Bletch - 1;
1588
+ dval(d) /= bigtens[n_bigtens-1];
1589
+ ieps++;
1590
+ }
1591
+ for (; j; j >>= 1, i++)
1592
+ if (j & 1) {
1593
+ ieps++;
1594
+ ds *= bigtens[i];
1595
+ }
1596
+ dval(d) /= ds;
1597
+ }
1598
+ else if ((j1 = -k) != 0) {
1599
+ dval(d) *= tens[j1 & 0xf];
1600
+ for (j = j1 >> 4; j; j >>= 1, i++)
1601
+ if (j & 1) {
1602
+ ieps++;
1603
+ dval(d) *= bigtens[i];
1604
+ }
1605
+ }
1606
+ if (k_check && dval(d) < 1. && ilim > 0) {
1607
+ if (ilim1 <= 0)
1608
+ goto fast_failed;
1609
+ ilim = ilim1;
1610
+ k--;
1611
+ dval(d) *= 10.;
1612
+ ieps++;
1613
+ }
1614
+ dval(eps) = ieps*dval(d) + 7.;
1615
+ word0(eps) -= (P-1)*Exp_msk1;
1616
+ if (ilim == 0) {
1617
+ S = mhi = 0;
1618
+ dval(d) -= 5.;
1619
+ if (dval(d) > dval(eps))
1620
+ goto one_digit;
1621
+ if (dval(d) < -dval(eps))
1622
+ goto no_digits;
1623
+ goto fast_failed;
1624
+ }
1625
+ #ifndef No_leftright
1626
+ if (leftright) {
1627
+ /* Use Steele & White method of only
1628
+ * generating digits needed.
1629
+ */
1630
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
1631
+ for (i = 0;;) {
1632
+ L = (int)dval(d);
1633
+ dval(d) -= L;
1634
+ *s++ = '0' + (int)L;
1635
+ if (dval(d) < dval(eps))
1636
+ goto ret1;
1637
+ if (1. - dval(d) < dval(eps))
1638
+ goto bump_up;
1639
+ if (++i >= ilim)
1640
+ break;
1641
+ dval(eps) *= 10.;
1642
+ dval(d) *= 10.;
1643
+ }
1644
+ }
1645
+ else {
1646
+ #endif
1647
+ /* Generate ilim digits, then fix them up. */
1648
+ dval(eps) *= tens[ilim-1];
1649
+ for (i = 1;; i++, dval(d) *= 10.) {
1650
+ L = (Long)(dval(d));
1651
+ if (!(dval(d) -= L))
1652
+ ilim = i;
1653
+ *s++ = '0' + (int)L;
1654
+ if (i == ilim) {
1655
+ if (dval(d) > 0.5 + dval(eps))
1656
+ goto bump_up;
1657
+ else if (dval(d) < 0.5 - dval(eps)) {
1658
+ while (*--s == '0') ;
1659
+ s++;
1660
+ goto ret1;
1661
+ }
1662
+ break;
1663
+ }
1664
+ }
1665
+ #ifndef No_leftright
1666
+ }
1667
+ #endif
1668
+ fast_failed:
1669
+ s = s0;
1670
+ dval(d) = dval(d2);
1671
+ k = k0;
1672
+ ilim = ilim0;
1673
+ }
1674
+
1675
+ /* Do we have a "small" integer? */
1676
+
1677
+ if (be >= 0 && k <= Int_max) {
1678
+ /* Yes. */
1679
+ ds = tens[k];
1680
+ if (ndigits < 0 && ilim <= 0) {
1681
+ S = mhi = 0;
1682
+ if (ilim < 0 || dval(d) <= 5*ds)
1683
+ goto no_digits;
1684
+ goto one_digit;
1685
+ }
1686
+ for (i = 1;; i++, dval(d) *= 10.) {
1687
+ L = (Long)(dval(d) / ds);
1688
+ dval(d) -= L*ds;
1689
+ #ifdef Check_FLT_ROUNDS
1690
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
1691
+ if (dval(d) < 0) {
1692
+ L--;
1693
+ dval(d) += ds;
1694
+ }
1695
+ #endif
1696
+ *s++ = '0' + (int)L;
1697
+ if (!dval(d)) {
1698
+ #ifdef SET_INEXACT
1699
+ inexact = 0;
1700
+ #endif
1701
+ break;
1702
+ }
1703
+ if (i == ilim) {
1704
+ #ifdef Honor_FLT_ROUNDS
1705
+ if (mode > 1)
1706
+ switch (rounding) {
1707
+ case 0: goto ret1;
1708
+ case 2: goto bump_up;
1709
+ }
1710
+ #endif
1711
+ dval(d) += dval(d);
1712
+ if (dval(d) > ds || (dval(d) == ds && (L & 1))) {
1713
+ bump_up:
1714
+ while (*--s == '9')
1715
+ if (s == s0) {
1716
+ k++;
1717
+ *s = '0';
1718
+ break;
1719
+ }
1720
+ ++*s++;
1721
+ }
1722
+ break;
1723
+ }
1724
+ }
1725
+ goto ret1;
1726
+ }
1727
+
1728
+ m2 = b2;
1729
+ m5 = b5;
1730
+ if (leftright) {
1731
+ i =
1732
+ #ifndef Sudden_Underflow
1733
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
1734
+ #endif
1735
+ #ifdef IBM
1736
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
1737
+ #else
1738
+ 1 + P - bbits;
1739
+ #endif
1740
+ b2 += i;
1741
+ s2 += i;
1742
+ mhi = i2b(1);
1743
+ }
1744
+ if (m2 > 0 && s2 > 0) {
1745
+ i = m2 < s2 ? m2 : s2;
1746
+ b2 -= i;
1747
+ m2 -= i;
1748
+ s2 -= i;
1749
+ }
1750
+ if (b5 > 0) {
1751
+ if (leftright) {
1752
+ if (m5 > 0) {
1753
+ mhi = pow5mult(mhi, m5);
1754
+ b1 = mult(mhi, b);
1755
+ Bfree(b);
1756
+ b = b1;
1757
+ }
1758
+ if ((j = b5 - m5) != 0)
1759
+ b = pow5mult(b, j);
1760
+ }
1761
+ else
1762
+ b = pow5mult(b, b5);
1763
+ }
1764
+ S = i2b(1);
1765
+ if (s5 > 0)
1766
+ S = pow5mult(S, s5);
1767
+
1768
+ /* Check for special case that d is a normalized power of 2. */
1769
+
1770
+ spec_case = 0;
1771
+ if ((mode < 2 || leftright)
1772
+ #ifdef Honor_FLT_ROUNDS
1773
+ && rounding == 1
1774
+ #endif
1775
+ ) {
1776
+ if (!word1(d) && !(word0(d) & Bndry_mask)
1777
+ #ifndef Sudden_Underflow
1778
+ && word0(d) & (Exp_mask & ~Exp_msk1)
1779
+ #endif
1780
+ ) {
1781
+ /* The special case */
1782
+ b2 += Log2P;
1783
+ s2 += Log2P;
1784
+ spec_case = 1;
1785
+ }
1786
+ }
1787
+
1788
+ /* Arrange for convenient computation of quotients:
1789
+ * shift left if necessary so divisor has 4 leading 0 bits.
1790
+ *
1791
+ * Perhaps we should just compute leading 28 bits of S once
1792
+ * and for all and pass them and a shift to quorem, so it
1793
+ * can do shifts and ors to compute the numerator for q.
1794
+ */
1795
+ #ifdef Pack_32
1796
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
1797
+ i = 32 - i;
1798
+ #else
1799
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0)
1800
+ i = 16 - i;
1801
+ #endif
1802
+ if (i > 4) {
1803
+ i -= 4;
1804
+ b2 += i;
1805
+ m2 += i;
1806
+ s2 += i;
1807
+ }
1808
+ else if (i < 4) {
1809
+ i += 28;
1810
+ b2 += i;
1811
+ m2 += i;
1812
+ s2 += i;
1813
+ }
1814
+ if (b2 > 0)
1815
+ b = lshift(b, b2);
1816
+ if (s2 > 0)
1817
+ S = lshift(S, s2);
1818
+ if (k_check) {
1819
+ if (bicmp(b,S) < 0) {
1820
+ k--;
1821
+ b = multadd(b, 10, 0); /* we botched the k estimate */
1822
+ if (leftright)
1823
+ mhi = multadd(mhi, 10, 0);
1824
+ ilim = ilim1;
1825
+ }
1826
+ }
1827
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
1828
+ if (ilim < 0 || bicmp(b,S = multadd(S,5,0)) <= 0) {
1829
+ /* no digits, fcvt style */
1830
+ no_digits:
1831
+ k = -1 - ndigits;
1832
+ goto ret;
1833
+ }
1834
+ one_digit:
1835
+ *s++ = '1';
1836
+ k++;
1837
+ goto ret;
1838
+ }
1839
+ if (leftright) {
1840
+ if (m2 > 0)
1841
+ mhi = lshift(mhi, m2);
1842
+
1843
+ /* Compute mlo -- check for special case
1844
+ * that d is a normalized power of 2.
1845
+ */
1846
+
1847
+ mlo = mhi;
1848
+ if (spec_case) {
1849
+ mhi = Balloc(mhi->k);
1850
+ Bcopy(mhi, mlo);
1851
+ mhi = lshift(mhi, Log2P);
1852
+ }
1853
+
1854
+ for (i = 1;;i++) {
1855
+ dig = quorem(b,S) + '0';
1856
+ /* Do we yet have the shortest decimal string
1857
+ * that will round to d?
1858
+ */
1859
+ j = bicmp(b, mlo);
1860
+ delta = diff(S, mhi);
1861
+ j1 = delta->sign ? 1 : bicmp(b, delta);
1862
+ Bfree(delta);
1863
+ #ifndef ROUND_BIASED
1864
+ if (j1 == 0 && mode != 1 && !(word1(d) & 1)
1865
+ #ifdef Honor_FLT_ROUNDS
1866
+ && rounding >= 1
1867
+ #endif
1868
+ ) {
1869
+ if (dig == '9')
1870
+ goto round_9_up;
1871
+ if (j > 0)
1872
+ dig++;
1873
+ #ifdef SET_INEXACT
1874
+ else if (!b->x[0] && b->wds <= 1)
1875
+ inexact = 0;
1876
+ #endif
1877
+ *s++ = dig;
1878
+ goto ret;
1879
+ }
1880
+ #endif
1881
+ if (j < 0 || (j == 0 && mode != 1
1882
+ #ifndef ROUND_BIASED
1883
+ && !(word1(d) & 1)
1884
+ #endif
1885
+ )) {
1886
+ if (!b->x[0] && b->wds <= 1) {
1887
+ #ifdef SET_INEXACT
1888
+ inexact = 0;
1889
+ #endif
1890
+ goto accept_dig;
1891
+ }
1892
+ #ifdef Honor_FLT_ROUNDS
1893
+ if (mode > 1)
1894
+ switch (rounding) {
1895
+ case 0: goto accept_dig;
1896
+ case 2: goto keep_dig;
1897
+ }
1898
+ #endif /*Honor_FLT_ROUNDS*/
1899
+ if (j1 > 0) {
1900
+ b = lshift(b, 1);
1901
+ j1 = bicmp(b, S);
1902
+ if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')
1903
+ goto round_9_up;
1904
+ }
1905
+ accept_dig:
1906
+ *s++ = dig;
1907
+ goto ret;
1908
+ }
1909
+ if (j1 > 0) {
1910
+ #ifdef Honor_FLT_ROUNDS
1911
+ if (!rounding)
1912
+ goto accept_dig;
1913
+ #endif
1914
+ if (dig == '9') { /* possible if i == 1 */
1915
+ round_9_up:
1916
+ *s++ = '9';
1917
+ goto roundoff;
1918
+ }
1919
+ *s++ = dig + 1;
1920
+ goto ret;
1921
+ }
1922
+ #ifdef Honor_FLT_ROUNDS
1923
+ keep_dig:
1924
+ #endif
1925
+ *s++ = dig;
1926
+ if (i == ilim)
1927
+ break;
1928
+ b = multadd(b, 10, 0);
1929
+ if (mlo == mhi)
1930
+ mlo = mhi = multadd(mhi, 10, 0);
1931
+ else {
1932
+ mlo = multadd(mlo, 10, 0);
1933
+ mhi = multadd(mhi, 10, 0);
1934
+ }
1935
+ }
1936
+ }
1937
+ else
1938
+ for (i = 1;; i++) {
1939
+ *s++ = dig = quorem(b,S) + '0';
1940
+ if (!b->x[0] && b->wds <= 1) {
1941
+ #ifdef SET_INEXACT
1942
+ inexact = 0;
1943
+ #endif
1944
+ goto ret;
1945
+ }
1946
+ if (i >= ilim)
1947
+ break;
1948
+ b = multadd(b, 10, 0);
1949
+ }
1950
+
1951
+ /* Round off last digit */
1952
+
1953
+ #ifdef Honor_FLT_ROUNDS
1954
+ switch (rounding) {
1955
+ case 0: goto trimzeros;
1956
+ case 2: goto roundoff;
1957
+ }
1958
+ #endif
1959
+ b = lshift(b, 1);
1960
+ j = bicmp(b, S);
1961
+ if (j > 0 || (j == 0 && (dig & 1))) {
1962
+ roundoff:
1963
+ while (*--s == '9')
1964
+ if (s == s0) {
1965
+ k++;
1966
+ *s++ = '1';
1967
+ goto ret;
1968
+ }
1969
+ ++*s++;
1970
+ }
1971
+ else {
1972
+ while (*--s == '0') ;
1973
+ s++;
1974
+ }
1975
+ ret:
1976
+ Bfree(S);
1977
+ if (mhi) {
1978
+ if (mlo && mlo != mhi)
1979
+ Bfree(mlo);
1980
+ Bfree(mhi);
1981
+ }
1982
+ ret1:
1983
+ #ifdef SET_INEXACT
1984
+ if (inexact) {
1985
+ if (!oldinexact) {
1986
+ word0(d) = Exp_1 + (70 << Exp_shift);
1987
+ word1(d) = 0;
1988
+ dval(d) += 1.;
1989
+ }
1990
+ }
1991
+ else if (!oldinexact)
1992
+ clear_inexact();
1993
+ #endif
1994
+ Bfree(b);
1995
+ *s = 0;
1996
+ *decpt = k + 1;
1997
+ if (rve)
1998
+ *rve = s;
1999
+ return s0;
2000
+ }
2001
+
2002
+ /*
2003
+ * copied from bignum.c
2004
+ */
2005
+
2006
+ #define BDIGITS(x) (RBIGNUM_DIGITS(x))
2007
+
2008
+ static VALUE
2009
+ rb_big_uminus(VALUE x)
2010
+ {
2011
+ VALUE z = rb_big_clone(x);
2012
+
2013
+ RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
2014
+
2015
+ return rb_big_norm(z); /* modified to use exported one */
2016
+ }
2017
+
2018
+ static VALUE
2019
+ rb_big_hash(VALUE x)
2020
+ {
2021
+ st_index_t hash;
2022
+
2023
+ hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*RBIGNUM_LEN(x)) ^ RBIGNUM_SIGN(x);
2024
+ return INT2FIX(hash);
2025
+ }
2026
+
2027
+ static VALUE
2028
+ rb_big_odd_p(VALUE num)
2029
+ {
2030
+ if (BDIGITS(num)[0] & 1) {
2031
+ return Qtrue;
2032
+ }
2033
+ return Qfalse;
2034
+ }
2035
+
2036
+ /*
2037
+ * copied from numeric.c
2038
+ */
2039
+
2040
+ static VALUE
2041
+ flo_to_s(VALUE flt)
2042
+ {
2043
+ char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
2044
+ enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
2045
+ enum {float_dig = DBL_DIG+1};
2046
+ char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
2047
+ double value = RFLOAT_VALUE(flt);
2048
+ VALUE s;
2049
+ char *p, *e;
2050
+ int sign, decpt, digs;
2051
+
2052
+ if (isinf(value))
2053
+ return rb_usascii_str_new2(value < 0 ? "-Infinity" : "Infinity");
2054
+ else if (isnan(value))
2055
+ return rb_usascii_str_new2("NaN");
2056
+
2057
+ p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
2058
+ s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
2059
+ if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
2060
+ memcpy(buf, p, digs);
2061
+ xfree(p);
2062
+ if (decpt > 0) {
2063
+ if (decpt < digs) {
2064
+ memmove(buf + decpt + 1, buf + decpt, digs - decpt);
2065
+ buf[decpt] = '.';
2066
+ rb_str_cat(s, buf, digs + 1);
2067
+ }
2068
+ else if (decpt <= DBL_DIG) {
2069
+ long len;
2070
+ char *ptr;
2071
+ rb_str_cat(s, buf, digs);
2072
+ rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
2073
+ ptr = RSTRING_PTR(s) + len;
2074
+ if (decpt > digs) {
2075
+ memset(ptr, '0', decpt - digs);
2076
+ ptr += decpt - digs;
2077
+ }
2078
+ memcpy(ptr, ".0", 2);
2079
+ }
2080
+ else {
2081
+ goto exp;
2082
+ }
2083
+ }
2084
+ else if (decpt > -4) {
2085
+ long len;
2086
+ char *ptr;
2087
+ rb_str_cat(s, "0.", 2);
2088
+ rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
2089
+ ptr = RSTRING_PTR(s);
2090
+ memset(ptr += len, '0', -decpt);
2091
+ memcpy(ptr -= decpt, buf, digs);
2092
+ }
2093
+ else {
2094
+ exp:
2095
+ if (digs > 1) {
2096
+ memmove(buf + 2, buf + 1, digs - 1);
2097
+ }
2098
+ else {
2099
+ buf[2] = '0';
2100
+ digs++;
2101
+ }
2102
+ buf[1] = '.';
2103
+ rb_str_cat(s, buf, digs + 1);
2104
+ rb_str_catf(s, "e%+03d", decpt - 1);
2105
+ }
2106
+ return s;
2107
+ }
2108
+
2109
+ static VALUE
2110
+ fix_plus(VALUE x, VALUE y)
2111
+ {
2112
+ if (FIXNUM_P(y)) {
2113
+ long a, b, c;
2114
+ VALUE r;
2115
+
2116
+ a = FIX2LONG(x);
2117
+ b = FIX2LONG(y);
2118
+ c = a + b;
2119
+ r = LONG2NUM(c);
2120
+
2121
+ return r;
2122
+ }
2123
+ return rb_big_plus(y, x); /* modified */
2124
+ }
2125
+
2126
+ static VALUE
2127
+ fix_minus(VALUE x, VALUE y)
2128
+ {
2129
+ if (FIXNUM_P(y)) {
2130
+ long a, b, c;
2131
+ VALUE r;
2132
+
2133
+ a = FIX2LONG(x);
2134
+ b = FIX2LONG(y);
2135
+ c = a - b;
2136
+ r = LONG2NUM(c);
2137
+
2138
+ return r;
2139
+ }
2140
+ /* modified */
2141
+ x = rb_int2big(FIX2LONG(x));
2142
+ return rb_big_minus(x, y);
2143
+ }
2144
+
2145
+ #define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
2146
+ /*tests if N*N would overflow*/
2147
+ #define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
2148
+
2149
+ static VALUE
2150
+ fix_mul(VALUE x, VALUE y)
2151
+ {
2152
+ if (FIXNUM_P(y)) {
2153
+ #ifdef __HP_cc
2154
+ /* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */
2155
+ volatile
2156
+ #endif
2157
+ long a, b;
2158
+ #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
2159
+ LONG_LONG d;
2160
+ #else
2161
+ VALUE r;
2162
+ #endif
2163
+
2164
+ a = FIX2LONG(x);
2165
+ b = FIX2LONG(y);
2166
+
2167
+ #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
2168
+ d = (LONG_LONG)a * b;
2169
+ if (FIXABLE(d)) return LONG2FIX(d);
2170
+ return rb_ll2inum(d);
2171
+ #else
2172
+ if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
2173
+ return LONG2FIX(a*b);
2174
+ if (a == 0) return x;
2175
+ if (MUL_OVERFLOW_FIXNUM_P(a, b))
2176
+ r = rb_big_mul(rb_int2big(a), rb_int2big(b));
2177
+ else
2178
+ r = LONG2FIX(a * b);
2179
+ return r;
2180
+ #endif
2181
+ }
2182
+ /* modified */
2183
+ return rb_big_mul(y, x);
2184
+ }
2185
+
2186
+ static void
2187
+ fixdivmod(long x, long y, long *divp, long *modp)
2188
+ {
2189
+ long div, mod;
2190
+
2191
+ if (y == 0) rb_bug("fixdivmod(): not reached"); /* modified */
2192
+ if (y < 0) {
2193
+ if (x < 0)
2194
+ div = -x / -y;
2195
+ else
2196
+ div = - (x / -y);
2197
+ }
2198
+ else {
2199
+ if (x < 0)
2200
+ div = - (-x / y);
2201
+ else
2202
+ div = x / y;
2203
+ }
2204
+ mod = x - div*y;
2205
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
2206
+ mod += y;
2207
+ div -= 1;
2208
+ }
2209
+ if (divp) *divp = div;
2210
+ if (modp) *modp = mod;
2211
+ }
2212
+
2213
+ /* extracted from fix_divide() */
2214
+ static VALUE
2215
+ fix_div(VALUE x, VALUE y)
2216
+ {
2217
+ if (FIXNUM_P(y)) {
2218
+ long div;
2219
+
2220
+ fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0);
2221
+ return LONG2NUM(div);
2222
+ }
2223
+ /* modified */
2224
+ x = rb_int2big(FIX2LONG(x));
2225
+ return rb_big_div(x, y);
2226
+ }
2227
+
2228
+ static VALUE
2229
+ fix_divmod(VALUE x, VALUE y)
2230
+ {
2231
+ if (FIXNUM_P(y)) {
2232
+ long div, mod;
2233
+
2234
+ fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod);
2235
+
2236
+ return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod));
2237
+ }
2238
+ /* modified */
2239
+ x = rb_int2big(FIX2LONG(x));
2240
+ return rb_big_divmod(x, y);
2241
+ }
2242
+
2243
+ static VALUE
2244
+ int_pow(long x, unsigned long y)
2245
+ {
2246
+ int neg = x < 0;
2247
+ long z = 1;
2248
+
2249
+ if (neg) x = -x;
2250
+ if (y & 1)
2251
+ z = x;
2252
+ else
2253
+ neg = 0;
2254
+ y &= ~1;
2255
+ do {
2256
+ while (y % 2 == 0) {
2257
+ if (!FIT_SQRT_LONG(x)) {
2258
+ VALUE v;
2259
+ bignum:
2260
+ v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
2261
+ if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
2262
+ return v;
2263
+ }
2264
+ x = x * x;
2265
+ y >>= 1;
2266
+ }
2267
+ {
2268
+ if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
2269
+ goto bignum;
2270
+ }
2271
+ z = x * z;
2272
+ }
2273
+ } while (--y);
2274
+ if (neg) z = -z;
2275
+ return LONG2NUM(z);
2276
+ }
2277
+
2278
+ static VALUE fix_odd_p(VALUE num);
2279
+
2280
+ static VALUE
2281
+ fix_pow(VALUE x, VALUE y)
2282
+ {
2283
+ long a = FIX2LONG(x);
2284
+
2285
+ if (FIXNUM_P(y)) {
2286
+ long b = FIX2LONG(y);
2287
+
2288
+ if (a == 1) return INT2FIX(1);
2289
+ if (a == -1) {
2290
+ if (b % 2 == 0)
2291
+ return INT2FIX(1);
2292
+ else
2293
+ return INT2FIX(-1);
2294
+ }
2295
+ if (b < 0)
2296
+ rb_bug("fix_pow(): infinity returned");
2297
+
2298
+ if (b == 0) return INT2FIX(1);
2299
+ if (b == 1) return x;
2300
+ if (a == 0) {
2301
+ if (b > 0) return INT2FIX(0);
2302
+ return DBL2NUM(INFINITY);
2303
+ }
2304
+ return int_pow(a, b);
2305
+ }
2306
+ /* modified */
2307
+ if (a == 1) return INT2FIX(1);
2308
+ if (a == -1) {
2309
+ #define int_even_p(x) (FIXNUM_P(x) ? !fix_odd_p(x) : !rb_big_odd_p(x))
2310
+ if (int_even_p(y)) return INT2FIX(1);
2311
+ else return INT2FIX(-1);
2312
+ }
2313
+ #define negative_int_p(x) (FIXNUM_P(x) ? (FIX2LONG(x) < 0) : !RBIGNUM_SIGN(x))
2314
+ if (negative_int_p(y))
2315
+ return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
2316
+ if (a == 0) return INT2FIX(0);
2317
+ x = rb_int2big(FIX2LONG(x));
2318
+ return rb_big_pow(x, y);
2319
+ #undef int_even_p
2320
+ #undef negative_int_p
2321
+ }
2322
+
2323
+ static VALUE
2324
+ fix_equal(VALUE x, VALUE y)
2325
+ {
2326
+ if (x == y) return Qtrue;
2327
+ if (FIXNUM_P(y)) return Qfalse;
2328
+ return rb_big_eq(y, x); /* modified */
2329
+ }
2330
+
2331
+ static VALUE
2332
+ fix_cmp(VALUE x, VALUE y)
2333
+ {
2334
+ if (x == y) return INT2FIX(0);
2335
+ if (FIXNUM_P(y)) {
2336
+ if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1);
2337
+ return INT2FIX(-1);
2338
+ }
2339
+ /* modified */
2340
+ return rb_big_cmp(rb_int2big(FIX2LONG(x)), y);
2341
+ }
2342
+
2343
+ static VALUE
2344
+ fix_odd_p(VALUE num)
2345
+ {
2346
+ if (num & 2) {
2347
+ return Qtrue;
2348
+ }
2349
+ return Qfalse;
2350
+ }