decimal 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }