fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / t / pmc / bigint.t
blob4dc1164c599c23d984692bf995d9ff1eeed83b05
1 #!./parrot
2 # Copyright (C) 2001-2010, Parrot Foundation.
3 # $Id$
5 =head1 NAME
7 t/pmc/bigint.t - BigInt PMC
9 =head1 SYNOPSIS
11     % prove t/pmc/bigint.t
13 =head1 DESCRIPTION
15 Tests the BigInt PMC.
17 =cut
19 .sub main :main
21     .include 'test_more.pir'
23     plan(36)
24     check_libgmp_good()
26     set_and_get()
27     addition()
28     subtraction()
29     multiplication()
30     division()
31     negation()
32     division_by_zero()
33     negate_min_integer()
34     absolute_value()
35     absolute_min_integer()
36     overflow_coercion()
37     interface()
38     boolean()
39     pi()
40     bugfixes()
42 .end
44 .include 'iglobals.pasm'
45 .include 'fp_equality.pasm'
46 .include 'errors.pasm'
48 .sub check_libgmp_good
49     # check libgmp included in Parrot build
50     $P0 = getinterp
51     $P1 = $P0[.IGLOBALS_CONFIG_HASH]
53     $P2 = $P1['gmp']
54     $I1 = isnull $P2
55     if $I1, NoLibGMP
56     say '# This Parrot uses GMP'
58     # check version is >= 4.1.4
59     $P0 = new ['BigInt']
60     $S3 = $P0.'version'()
61     $P1 = split '.', $S3
62     $S0 = $P1[0]
63     $I0 = $S0
64     gt $I0, 4, Config2
65     lt $I0, 4, OldLibGMP
66     $S1 = $P1[1]
67     $I1 = $S1
68     gt $I1, 1, Config2
69     lt $I1, 1, OldLibGMP
70     $S2 = $P1[2]
71     $I2 = $S2
72     lt $I2, 4, OldLibGMP
74 Config2:
75     diag( 'Suitable GMP version [', $S3, '] available' )
76     goto ret
78 NoLibGMP:
79     diag( 'No BigInt Lib configured' )
80     skip(36)
81     exit 0
83 OldLibGMP:
84     diag( 'Buggy GMP version [', $S3, '] with huge digit multiply - please upgrade' )
85     skip(36)
86     exit 0
88 ret:
89 .end
91 .sub set_and_get
92     $I1 = 1
93     $P0 = new ['BigInt']
94     $I0 = 999999
95     $P0 = $I0
96     $I2 = $P0
97     eq $I0, $I2, OK1
98     $I1 = 0
99     say 'set_int/get_int 999999 wrong'
100 OK1:
102     $P0 = new ['BigInt']
103     $I0 = 999999
104     $P0 = $I0
105     $S0 = get_repr $P0
106     $I2 = $S0
107     eq $I0, $I2, OK2
108     $I1 = 0
109     say 'set_int/get_str 999999 wrong'
110 OK2:
112     $P0 = new ['BigInt']
113     $P0 = 999999
114     $N1 = $P0
115     .fp_eq($N1, 999999.0, OK3)
116     $I1 = 0
117     say 'set_int/get_num 999999 wrong'
118 OK3:
120     $P0 = -999999
121     $N1 = $P0
122     .fp_eq($N1, -999999.0, OK4)
123     $I1 = 0
124     say 'set_int/get_num -999999 wrong'
125 OK4:
127     $P0 = 2147483646
128     $N1 = $P0
129     .fp_eq($N1, 2.147483646e9, OK5)
130     $I1 = 0
131     say 'set_int/get_num 2^31-1 wrong'
132 OK5:
134     $P0 = -2147483646
135     $N1 = $P0
136     .fp_eq($N1, -2.147483646e9, OK6)
137     $I1 = 0
138     say 'set_int/get_num 2-2^31 wrong'
139 OK6:
141     $P0 = new ['BigInt']
142     $P0 = 1.23e12
143     $S0 = $P0
144     eq $S0, '1230000000000', OK7
145     $I1 = 0
146     say 'set_num/get_str 1230000000000'
147 OK7:
149     $P0 = new ['BigInt']
150     $P0 = '1230000000000'
151     $S0 = $P0
152     eq $S0, '1230000000000', OK8
153     $I1 = 0
154     say 'set_str/get_str 1230000000000'
156 OK8:
157     ok($I1, 'set and get combinations')
158 .end
160 .sub addition
161     $I1 = 1
162     $P0 = new ['BigInt']
163     $P0 = 999999
164     $P1 = new ['BigInt']
165     $P1 = 1000000
166     $P2 = new ['BigInt']
167     $P2 = add $P0, $P1
168     $S0 = $P2
169     eq $S0, '1999999', OK1
170     $I1 = 0
171     say 'add 999999+1000000 wrong'
172 OK1:
174     $P0 = '12345678987654321'
175     $P1 = '10000000000000000'
176     $P2 = add $P1, $P0
177     $S0 = $P2
178     eq $S0,'22345678987654321',OK2
179     $I1 = 0
180     say 'add 12345678987654321+10000000000000000 wrong'
181 OK2:
182     ok($I1, 'add(bigint,bigint)')
184     $I1 = 1
185     $P0 = 999999
186     $P2 = add $P0, 1000000
187     $S0 = $P2
188     eq $S0,'1999999',OK3
189     $I1 = 0
190     say 'add 999999+1000000 wrong'
191 OK3:
193     $P0 = '100000000000000000000'
194     $P2 = add $P0, 1000000
195     $S0 = $P2
196     eq $S0,'100000000000001000000',OK4
197     $I1 = 0
198     say 'add 100000000000000000000+1000000 wrong'
199 OK4:
200     ok($I1, 'add(bigint,nativeint)')
202 .end
204 .sub subtraction
205     $I1 = 1
206     $P0 = new ['BigInt']
207     $P0 = 12345678
208     $P1 = new ['BigInt']
209     $P1 = 5678
210     $P2 = new ['BigInt']
211     $P2 = sub $P0, $P1
212     $I0 = $P2
213     eq $I0, 12340000, OK1
214     $I1 = 0
215     say 'sub 12345678-5678 wrong'
216 OK1:
218     $P0 = '123456789012345678'
219     $P2 = sub $P0, $P1
220     $P3 = new ['BigInt']
221     $P3 = '123456789012340000'
222     eq $P2, $P3, OK2
223     $I1 = 0
224     say 'sub 123456789012345678-5678 wrong'
225 OK2:
227     $P1 = '223456789012345678'
228     $P2 = sub $P0, $P1
229     $P3 = '-100000000000000000'
230     eq $P2, $P3, OK3
231     $I1 = 0
232     say 'sub 123456789012345678-(-100000000000000000) wrong'
233 OK3:
234     ok($I1, 'sub(bigint,bigint)')
235     $I1 = 1
237     $P0 = 12345678
238     $P2 = sub $P0, 5678
239     $I0 = $P2
240     eq $I0, 12340000, OK4
241     $I1 = 0
242     say 'sub 12345678-5678 wrong'
243 OK4:
245     $P0 = '123456789012345678'
246     $P2 = sub $P0, 5678
247     $P3 = new ['BigInt']
248     $P3 = '123456789012340000'
249     eq $P2, $P3, OK5
250     $I1 = 0
251     say 'sub 123456789012345678-5678 wrong'
252 OK5:
254     $P0 = new ['BigInt']
255     $P0 = 12345678
256     $P1 = new ['Integer']
257     $P1 = 5678
258     $P2 = new ['BigInt']
259     $P2 = sub $P0, $P1
260     $I0 = $P2
261     eq $I0, 12340000, OK6
262     $I1 = 0
263     say 'sub 12345678-5678 wrong'
264 OK6:
266     $P0 = '123456789012345678'
267     $P2 = sub $P0, $P1
268     $P3 = new ['BigInt']
269     $P3 = '123456789012340000'
270     eq $P2, $P3, OK7
271     $I1 = 0
272     say 'sub 123456789012345678-5678 wrong'
273 OK7:
275     $P0 = 9876543
276     $P4 = new ['Integer']
277     $P4 = 44
278     $P2 = sub $P0, $P4
279     $I0 = $P2
280     eq $I0, 9876499, OK8
281     $I1 = 0
282     say 'sub 9876543-44 wrong'
283 OK8:
285     $P0 = '9876543219876543'
286     $P2 = sub $P0, $P4
287     $P3 = '9876543219876499'
288     eq $P3, $P2, OK9
289     $I1 = 0
290     say 'sub 9876543219876543-44 wrong'
291 OK9:
292     ok($I1, 'sub(bigint,integer)')
293 .end
295 .sub multiplication
296     $P0 = new ['BigInt']
297     $P0 = 999999
298     $P1 = new ['BigInt']
299     $P1 = 1000000
300     $P2 = new ['BigInt']
301     $P2 = mul $P0, $P1
302     $S0 = $P2
303     is($S0, '999999000000', 'mul(bigint,bigint)')
305     $P0 = new ['BigInt']
306     $P0 = 999999
307     $P2 = new ['BigInt']
308     $P2 = mul $P0, 1000000
309     is($P2, '999999000000', 'mul(bigint,nativeint)')
310 .end
312 .sub division
313     $I1 = 1
314     $P0 = new ['BigInt']
315     $P0 = '100000000000000000000'
316     $P1 = new ['BigInt']
317     $P1 = '100000000000000000000'
318     $P2 = new ['BigInt']
319     $P2 = div $P0, $P1
320     $I0 = $P2
321     eq $I0, 1, OK1
322     $I1 = 0
323     say 'div 100000000000000000000/100000000000000000000 wrong'
324 OK1:
326     $P3 = new ['BigInt']
327     $P3 = '10000000000000'
328     $P1 = 10000000
329     $P2 = div $P0, $P1
330     eq $P2, $P3, OK2
331     $I1 = 0
332     say 'div 100000000000000000000/10000000 wrong'
333 OK2:
335     $P1 = 10
336     $P3 = '10000000000000000000'
337     $P2 = div $P0, $P1
338     eq $P2, $P3, OK3
339     $I1 = 0
340     say 'div 100000000000000000000/10 wrong'
341 OK3:
343     $P1 = -1
344     $P3 = '-100000000000000000000'
345     $P2 = div $P0, $P1
346     eq $P2, $P3, OK4
347     $I1 = 0
348     say 'div 100000000000000000000/(-1) wrong'
349 OK4:
350     ok($I1, 'div(bigint,bigint)')
351     $I1 = 1
353     $P0 = new ['BigInt']
354     $P0 = '100000000000000000000'
355     $P1 = new ['BigInt']
356     $P1 = div $P0, 10
357     $P2 = new ['BigInt']
358     $P2 = '10000000000000000000'
359     eq $P1, $P2, OK5
360     $I1 = 0
361     say 'div 100000000000000000000/10 wrong'
362 OK5:
364     $P0 = '100000000000000'
365     $P1 = div $P0, 10000000
366     $P2 = 10000000
367     eq $P1, $P2, OK6
368     $I1 = 0
369     say 'div 100000000000000/10000000 wrong'
370 OK6:
371     ok($I1, 'div(bigint,nativeint)')
372     $I1 = 1
374     $P0 = new ['BigInt']
375     $P0 = '100000000000000000000'
376     $P1 = new ['BigInt']
377     $P3 = new ['Integer']
378     $P3 = 10
379     $P1 = div $P0, $P3
380     $P2 = new ['BigInt']
381     $P2 = '10000000000000000000'
382     eq $P1, $P2, OK7
383     $I1 = 0
384     say 'div 100000000000000000000/10 wrong'
385 OK7:
387     $P0 = '100000000000000'
388     $P4 = new ['Integer']
389     $P4 = 10000000
390     $P1 = div $P0, $P4
391     $P2 = 10000000
392     eq $P1, $P2, OK8
393     $I1 = 0
394     say 'div 100000000000000/10000000 wrong'
395 OK8:
396     ok($I1, 'div(bigint,integer)')
398 .end
400 .sub division_by_zero
401     $I1 = 1
402     $P0 = new ['BigInt']
403     $P0 = '1000000000000000000000'
404     $P1 = new ['BigInt']
405     ## divide by a zero BigInt
406     $P2 = new ['BigInt']
407     $P2 = 0
408     push_eh E1
409         $P1 = div $P0, $P2
410         $I1 = 0
411         say 'Failed to throw exception'
413     pop_eh
414     get_results '0', $P0
415     $S0 = $P0
416     eq $S0, 'Divide by zero', OK1
417     $I1 = 0
418     print $S0
419     say ' is wrong exception type'
420 OK1:
421     ok($I1, 'div(bigint,bigint 0) throws "Divide by zero" exception')
422     $I1 = 1
424     $P0 = new ['BigInt']
425     $P0 = '1000000000000000000000'
426     $P1 = new ['BigInt']
427     ## modulus by a zero BigInt
428     $P2 = new ['BigInt']
429     $P2 = 0
430     push_eh E2
431         $P1 = mod $P0, $P2
432         $I1 = 0
433         say 'Failed to throw exception'
435     pop_eh
436     get_results '0', $P0
437     $S0 = $P0
438     eq $S0, 'Divide by zero', OK2
439     $I1 = 0
440     print $S0
441     say ' is wrong exception type'
442 OK2:
443     ok($I1, 'mod(bigint,bigint 0) throws "Divide by zero" exception')
444     $I1 = 1
446     $P0 = new ['BigInt']
447     $P0 = '1000000000000000000000'
448     $P1 = new ['BigInt']
449     ## divide by a zero Integer
450     $P2 = new ['Integer']
451     $P2 = 0
452     push_eh E3
453         $P1 = div $P0, $P2
454         $I1 = 0
455         say 'Failed to throw exception'
457     pop_eh
458     get_results '0', $P0
459     $S0 = $P0
460     eq $S0, 'Divide by zero', OK3
461     $I1 = 0
462     print $S0
463     say ' is wrong exception type'
464 OK3:
465     ok($I1, 'div(bigint,integer 0) throws "Divide by zero" exception')
466     $I1 = 1
468     $P0 = new ['BigInt']
469     $P0 = '1000000000000000000000'
470     $P1 = new ['BigInt']
471     ## modulus by a zero Integer
472     $P2 = new ['Integer']
473     $P2 = 0
474     push_eh E4
475         $P1 = mod $P0, $P2
476         $I1 = 0
477         say 'Failed to throw exception'
479     pop_eh
480     get_results '0', $S0
481     eq $S0, 'Divide by zero', OK4
482     $I1 = 0
483     print $S0
484     say ' is wrong exception type'
485 OK4:
486     ok($I1, 'mod(bigint,integer 0) throws "Divide by zero" exception')
488 .end
490 .sub negation
491     $I1 = 1
492     $P0 = new ['BigInt']
493     $P1 = new ['BigInt']
494     $P0 = '123456789123456789'
495     neg $P0
496     $P1 = '-123456789123456789'
497     eq $P0, $P1, OK1
498     $I1 = 0
499 OK1:
500     $P0 = '-123456789123456789'
501     neg $P0
502     $P1 = '123456789123456789'
503     eq $P0, $P1, OK2
504     $I1 = 0
505 OK2:
506     ok($I1, 'negation')
507 .end
509 .sub 'get_int_minmax'
510     .local int min, max
512     $P0 = getinterp
513     $P1 = $P0[.IGLOBALS_CONFIG_HASH]
514     $I0 = $P1['intvalsize']
516     # XXX can't use sysinfo (from sys_ops) in coretest
517     # build up 2's compliment min and max integers manually
518     max = 0x7F
519     min = 0x80
520     dec $I0
521   loop:
522     unless $I0 goto end_loop
523     min <<= 8
524     max <<= 8
525     max  |= 0xFF
526     dec $I0
527     goto loop
528   end_loop:
530     .return (min, max)
531 .end
533 .sub negate_min_integer
534     .local int max
535     .local int min
536     .local pmc max_1
537     .local pmc neg_min
538     (min, max) = 'get_int_minmax'()
539     max_1 = box max
540     inc max_1
541     neg_min = box min
542     neg neg_min                         # Use 1-operand form of neg.
543     is(neg_min, max_1, 'negate minimum native integer')
544 .end
546 .sub absolute_value
547     $P0 = new ['BigInt']
548     $P0 = '-1230000000000000000000'
549     $P1 = new ['Undef']
550     $P1 = abs $P0
551     $S0 = $P1
552     is($S0,'1230000000000000000000','abs negates negative number')
553     $S0 = $P0
554     is($S0,'-1230000000000000000000','... and original unchanged with 2-arg form')
555     $P1 = abs $P1
556     $S0 = $P1
557     is($S0,'1230000000000000000000','... does not change to positive number')
558     $S0 = $P1
559     abs $P0
560     $S0 = $P0
561     is($S0,'1230000000000000000000','... and in-place works too')
562 .end
564 .sub absolute_min_integer
565     .local int max
566     .local int min
567     .local pmc max_1
568     .local pmc neg_min
569     .local pmc result
570     (min, max) = 'get_int_minmax'()
571     max_1 = box max
572     inc max_1
573     neg_min = box min
574     result = abs neg_min                # Use 2-operand form of abs.
575     is(result, max_1, 'absolute minimum native integer')
576 .end
578 .sub overflow_coercion
579     # check libgmp included in Parrot build
580     $P0 = getinterp
581     $P4 = $P0[.IGLOBALS_CONFIG_HASH]
582     $I0 = $P4['intvalsize']
583     eq $I0, 8, sz8
584     eq $I0, 4, sz4
585     print 'Cannot cope with sizeof(INTVAL) == '
586     say $I0
587     skip(43)
588     exit 1
590 sz8:
591     $I3 = 0x100000000               # sqrt(2*(MinInt+1))
592     $I4 = 9223372036854775806       # MaxInt-1 == 2**63-2
593     $I5 = 9223372036854775807       # MaxInt
594     $S5 = '9223372036854775807'     # MaxInt
595     $S6 = '9223372036854775808'     # MaxInt+1
596     $S7 = '9223372036854775809'     # MaxInt+2
597     $I8 = -9223372036854775807      # MinInt+1 == 1-2**63
598     $I9 = -9223372036854775808      # MinInt
599     $S9 = '-9223372036854775808'    # MinInt
600     $S10 = '-9223372036854775809'   # MinInt-1
601     $S11 = '-9223372036854775810'   # MinInt-2
602     goto esz
604 sz4:
605     $I3 = 0x10000                   # sqrt(2*(MinInt+1))
606     $I4 = 2147483646                # MaxInt-1 == 2**31-2
607     $I5 = 2147483647                # MaxInt
608     $S5 = '2147483647'              # MaxInt
609     $S6 = '2147483648'              # MaxInt+1
610     $S7 = '2147483649'              # MaxInt+2
611     $I8 = -2147483647               # MinInt+1 == 1-2**31
612     $I9 = -2147483648               # MinInt
613     $S9 = '-2147483648'             # MinInt
614     $S10 = '-2147483649'            # MinInt-1
615     $S11 = '-2147483650'            # MinInt-2
616     goto esz
618 esz:
619     print '# Using '
620     $I0 = mul $I0, 8
621     print $I0
622     print '-bit Integers ['
623     print $I9
624     print '...'
625     print $I5
626     say ']'
628     # Checking upper bound by incremental increase
629     $I1 = 1
630     $P0 = new ['Integer']
631     $P0 = $I4               # MaxInt-1
632     $P1 = new ['Integer']
633     $P1 = 1
634     $P0 = add $P0, $P1
635     $S0 = typeof $P0
636     eq $S0, 'Integer', k0
637     $I1 = 0
638     say "typeof != 'Integer'"
640     $S0 = $P0
641     eq $S0, $S5, k1         # MaxInt
642     $I1 = 0
643     say 'value != MaxInt'
645     $P0 = add $P0, $P1
646     $S0 = typeof $P0
647     eq $S0, 'BigInt', k2
648     $I1 = 0
649     say "typeof != 'BigInt'"
651     $S0 = $P0
652     eq $S0, $S6, k3         # MaxInt+1
653     $I1 = 0
654     say 'value != MaxInt+1'
656     $P0 = add $P0, $P1
657     $S0 = typeof $P0
658     eq $S0, 'BigInt', k4
659     $I1 = 0
660     say "typeof != 'BigInt'"
662     $S0 = $P0
663     eq $S0, $S7, k5         # MaxInt+2
664     $I1 = 0
665     say 'value != MaxInt+2'
668     # Checking upper bound by increased steps
669     $P0 = new ['Integer']
670     $P0 = $I4               # MaxInt-1
671     $P2 = new ['Integer']
672     $P2 = add $P0, $P1
673     $S0 = typeof $P2
674     eq $S0, 'Integer', k6
675     $I1 = 0
676     say "typeof != 'Integer'"
678     $S0 = $P2
679     eq $S0, $S5, k7         # MaxInt
680     $I1 = 0
681     say 'value != MaxInt'
683     inc $P1
684     $P2 = new ['Integer']
685     $P2 = add $P0, $P1
686     $S0 = typeof $P2
687     eq $S0, 'BigInt', k8
688     $I1 = 0
689     say "typeof != 'BigInt'"
691     $S0 = $P2
692     eq $S0, $S6, k9         # MaxInt+1
693     $I1 = 0
694     say 'value != MaxInt+1'
696     add $P1, 1
697     $P2 = new ['Integer']
698     $P2 = add $P0, $P1
699     $S0 = typeof $P2
700     eq $S0, 'BigInt', k10
701     $I1 = 0
702     say "typeof != 'BigInt'"
703 k10:
704     $S0 = $P2
705     eq $S0, $S7, k11         # MaxInt+2
706     $I1 = 0
707     say 'value != MaxInt+2'
708 k11:
709     ok($I1, 'integer addition converts MaxInt+1 to BigInt')
711     # Checking lower bound
712     $I1 = 6
713     $P0 = new ['Integer']
714     $P0 = $I8
715     $P1 = -1
716     $P2 = new ['Integer']
717     $P2 = add $P0, $P1
718     $S0 = typeof $P2
719     ne $S0, 'Integer', k12
720     dec $I1
721 k12:
722     $S0 = $P2
723     ne $S0, $S9, k13
724     dec $I1
725 k13:
726     dec $P1
727     $P2 = new ['Integer']
728     $P2 = add $P0, $P1
729     $S0 = typeof $P2
730     ne $S0, 'BigInt', k14
731     dec $I1
732 k14:
733     $S0 = $P2
734     ne $S0, $S10, k15
735     dec $I1
736 k15:
737     sub $P1, 1
738     $P2 = new ['Integer']
739     $P2 = add $P0, $P1
740     $S0 = typeof $P2
741     ne $S0, 'BigInt', k16
742     dec $I1
743 k16:
744     $S0 = $P2
745     ne $S0, $S11, k17
746     dec $I1
747 k17:
748     is($I1, 0, 'integer addition converts MinInt+(-1) to BigInt')
750     $I1 = 6
751     $P0 = new ['Integer']
752     $P0 = $I4
753     $P1 = -1
754     $P2 = new ['Integer']
755     $P2 = sub $P0, $P1
756     $S0 = typeof $P2
757     ne $S0, 'Integer', k18
758     dec $I1
759 k18:
760     $S0 = $P2
761     ne $S0, $S5, k19
762     dec $I1
763 k19:
764     dec $P1
765     $P2 = new ['Integer']
766     $P2 = sub $P0, $P1
767     $S0 = typeof $P2
768     ne $S0, 'BigInt', k20
769     dec $I1
770 k20:
771     $S0 = $P2
772     ne $S0, $S6, k21
773     dec $I1
774 k21:
775     sub $P1, 1
776     $P2 = new ['Integer']
777     $P2 = sub $P0, $P1
778     $S0 = typeof $P2
779     ne $S0, 'BigInt', k22
780     dec $I1
781 k22:
782     $S0 = $P2
783     ne $S0, $S7, k23
784     dec $I1
785 k23:
786     is($I1, 0, 'integer subtraction converts MaxInt-(-1) to BigInt')
788     $I1 = 0
789     $P0 = new ['Integer']
790     $P0 = $I8   # MinInt
791     dec $P0
792     neg $P0
793     $S0 = typeof $P0
794     ne $S0, 'BigInt', k24
795     inc $I1
796 k24:
797     $S0 = $P0
798     ne $S0, $S6, k25
799     inc $I1
800 k25:
801     ok($I1, 'integer negation of MinInt converts to BigInt')
803     $I1 = 0
804     $P0 = new ['Integer']
805     $P0 = $I8   # MinInt
806     dec $P0
807     abs $P0
808     $S0 = typeof $P0
809     ne $S0, 'BigInt', k26
810     inc $I1
811 k26:
812     $S0 = $P0
813     ne $S0, $S6, k27
814     inc $I1
815 k27:
816     ok($I1, 'integer abs(MinInt) converts to BigInt')
818     $P0 = new ['Integer']
819     $P0 = $I3
820     $P1 = new ['Integer']
821     $P1 = $I3
824 .end
826 .sub interface
827     $P0 = new ['BigInt']
828     $I0 = does $P0, 'scalar'
829     is($I0,1,'Interface does scalar')
830     $I0 = does $P0, 'no_interface'
831     is($I0,0,'... and does not do bogus')
832 .end
834 .sub boolean
835     $P0 = new ['BigInt']
837     $P0 = '123456789123456789'
838     $I0 = 1
839     if $P0, OK1
840     $I0 = 0
841 OK1:
843     $P0 = 0
844     unless $P0, OK2
845     $I0 = 0
846 OK2:
848     ok($I0, 'truth and falsehood')
849 .end
851 # How this next test was originally written in Python:
853 #   class PI(object):
854 #       def __iter__(self):
855 #           k, a, b, a1, b1 = 2, 4, 1, 12, 4
856 #           while 1:
857 #               p, q, k = k*k, 2*k+1, k+1
858 #               a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
859 #               d, d1 = a//b, a1//b1
860 #               while d == d1:
861 #                   yield d
862 #                   a, a1 = 10*(a%b), 10*(a1%b1)
863 #                   d, d1 = a//b, a1//b1
865 #   pi = iter(PI())
866 #   ds = ""
867 #   for i in xrange(1, 1001):
868 #       d = pi.next()
869 #       ds += str(d)
870 #       im = i % 50
871 #       if im == 0:
872 #           print ds
873 #           ds = ""
875 #   print ds
878 .sub pi_generator
879     # k = $P6
880     $P6 = new ['Integer']
881     $P6 = 2
882     # a = $P7
883     $P7 = new ['Integer']
884     $P7 = 4
885     # b = $P8
886     $P8 = new ['Integer']
887     $P8 = 1
888     # a1 = $P9
889     $P9 = new ['Integer']
890     $P9 = 12
891     # b1 = $P10
892     $P10 = new ['Integer']
893     $P10 = 4
894 restart:
895     # p = $P11
896     $P11 = mul $P6, $P6
897     # q = $P12
898     $P12 = mul $P6, 2
899     inc $P12
900     inc $P6
901     # ta  = $P13
902     $P13 = clone $P9
903     # tb  = $P14
904     $P14 = clone $P10
905     $P0 = mul $P11, $P7
906     $P1 = mul $P12, $P9
907     # ta1 = $P15
908     $P15 =  add $P0, $P1
909     $P2 = mul $P11, $P8
910     $P3 = mul $P12, $P10
911     # tb1 = $P16
912     $P16 =  add $P2, $P3
913     $P7 = $P13
914     $P8 = $P14
915     $P9 = $P15
916     $P10 = $P16
917     # d = $P17
918     $P17 = fdiv $P7, $P8
919     # d1 = $P18
920     $P18 = fdiv $P9, $P10
921 next:
922     ne $P17, $P18, restart
923     .yield($P17)
924     $P4 = mod $P7, $P8
925     $P7 = mul $P4, 10
926     $P5 = mod $P9, $P10
927     $P9 = mul $P5, 10
928     $P17 = fdiv $P7, $P8
929     $P18 = fdiv $P9, $P10
930     goto next
931 .end
933 .sub pi
934     $S0 = <<'EoN'
935 31415926535897932384626433832795028841971693993751
936 05820974944592307816406286208998628034825342117067
937 98214808651328230664709384460955058223172535940812
938 84811174502841027019385211055596446229489549303819
939 64428810975665933446128475648233786783165271201909
940 14564856692346034861045432664821339360726024914127
941 37245870066063155881748815209209628292540917153643
942 67892590360011330530548820466521384146951941511609
943 43305727036575959195309218611738193261179310511854
944 80744623799627495673518857527248912279381830119491
945 29833673362440656643086021394946395224737190702179
946 86094370277053921717629317675238467481846766940513
947 20005681271452635608277857713427577896091736371787
948 21468440901224953430146549585371050792279689258923
949 54201995611212902196086403441815981362977477130996
950 05187072113499999983729780499510597317328160963185
951 95024459455346908302642522308253344685035261931188
952 17101000313783875288658753320838142061717766914730
953 35982534904287554687311595628638823537875937519577
954 81857780532171226806613001927876611195909216420198
957     $I3 = 0
958     $I4 = length $S0
959 loop:
960     $P0 = pi_generator()
961 skip_ws:
962     $S1 = substr $S0,$I3,1
963     eq $S1, '', stop
964     inc $I3
965     eq $S1, '.', skip_ws
966     eq $S1, ' ', skip_ws
967     eq $S1, "\r", skip_ws
968     eq $S1, "\n", skip_ws
969     $I1 = $S1
970     $I0 = $P0
971     eq $I0, $I1, loop
972 stop:
973     is($I0, $I1, 'Computed 1000 digits of PI (using coroutine)')
974     eq $I0, $I1, ret
975         print 'Wrong digit '
976         print $I0
977         print ' should have been '
978         print $S1
979         print ' at position '
980         print $I3
981         say '.'
982     ret:
983 .end
985 .sub bugfixes
987     $P0 = new ['BigInt']
988     $P0 = 1e10
989     $I1 = 1
990     gt $P0, 4, OK1
991     $I1 = 0
992 OK1:
993     ok($I1, 'BUG #34949 gt')
995     $P0 = new ['BigInt']
996     $P0 = 1e10
997     $I1 = 1
998     ge $P0, 4, OK2
999     $I1 = 0
1000 OK2:
1001     ok($I1, 'BUG #34949 ge')
1003     $P0 = new ['BigInt']
1004     $P0 = 1e10
1005     $I1 = 1
1006     ne $P0, 4, OK3
1007     $I1 = 0
1008 OK3:
1009     ok($I1, 'BUG #34949 ne')
1011     $P0 = new ['BigInt']
1012     $P0 = 1e10
1013     $I1 = 0
1014     eq $P0, 4, NOK4
1015     $I1 = 1
1016 NOK4:
1017     ok($I1, 'BUG #34949 eq')
1019     $P0 = new ['BigInt']
1020     $P0 = 1e10
1021     $I1 = 0
1022     lt $P0, 4, NOK5
1023     $I1 = 1
1024 NOK5:
1025     ok($I1, 'BUG #34949 le')
1027     $P0 = new ['BigInt']
1028     $P0 = 1e10
1029     $I1 = 0
1030     lt $P0, 4, NOK6
1031     $I1 = 1
1032 NOK6:
1033     ok($I1, 'BUG #34949 lt')
1035 .end
1037 # Local Variables:
1038 #   mode: pir
1039 #   fill-column: 100
1040 # End:
1041 # vim: expandtab shiftwidth=4 ft=pir: