2 # Copyright (C) 2001-2010, Parrot Foundation.
7 t/pmc/bigint.t - BigInt PMC
11 % prove t/pmc/bigint.t
21 .include 'test_more.pir'
35 absolute_min_integer()
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
51 $P1 = $P0[.IGLOBALS_CONFIG_HASH]
56 say '# This Parrot uses GMP'
58 # check version is >= 4.1.4
75 diag( 'Suitable GMP version [', $S3, '] available' )
79 diag( 'No BigInt Lib configured' )
84 diag( 'Buggy GMP version [', $S3, '] with huge digit multiply - please upgrade' )
99 say 'set_int/get_int 999999 wrong'
109 say 'set_int/get_str 999999 wrong'
115 .fp_eq($N1, 999999.0, OK3)
117 say 'set_int/get_num 999999 wrong'
122 .fp_eq($N1, -999999.0, OK4)
124 say 'set_int/get_num -999999 wrong'
129 .fp_eq($N1, 2.147483646e9, OK5)
131 say 'set_int/get_num 2^31-1 wrong'
136 .fp_eq($N1, -2.147483646e9, OK6)
138 say 'set_int/get_num 2-2^31 wrong'
144 eq $S0, '1230000000000', OK7
146 say 'set_num/get_str 1230000000000'
150 $P0 = '1230000000000'
152 eq $S0, '1230000000000', OK8
154 say 'set_str/get_str 1230000000000'
157 ok($I1, 'set and get combinations')
169 eq $S0, '1999999', OK1
171 say 'add 999999+1000000 wrong'
174 $P0 = '12345678987654321'
175 $P1 = '10000000000000000'
178 eq $S0,'22345678987654321',OK2
180 say 'add 12345678987654321+10000000000000000 wrong'
182 ok($I1, 'add(bigint,bigint)')
186 $P2 = add $P0, 1000000
190 say 'add 999999+1000000 wrong'
193 $P0 = '100000000000000000000'
194 $P2 = add $P0, 1000000
196 eq $S0,'100000000000001000000',OK4
198 say 'add 100000000000000000000+1000000 wrong'
200 ok($I1, 'add(bigint,nativeint)')
213 eq $I0, 12340000, OK1
215 say 'sub 12345678-5678 wrong'
218 $P0 = '123456789012345678'
221 $P3 = '123456789012340000'
224 say 'sub 123456789012345678-5678 wrong'
227 $P1 = '223456789012345678'
229 $P3 = '-100000000000000000'
232 say 'sub 123456789012345678-(-100000000000000000) wrong'
234 ok($I1, 'sub(bigint,bigint)')
240 eq $I0, 12340000, OK4
242 say 'sub 12345678-5678 wrong'
245 $P0 = '123456789012345678'
248 $P3 = '123456789012340000'
251 say 'sub 123456789012345678-5678 wrong'
256 $P1 = new ['Integer']
261 eq $I0, 12340000, OK6
263 say 'sub 12345678-5678 wrong'
266 $P0 = '123456789012345678'
269 $P3 = '123456789012340000'
272 say 'sub 123456789012345678-5678 wrong'
276 $P4 = new ['Integer']
282 say 'sub 9876543-44 wrong'
285 $P0 = '9876543219876543'
287 $P3 = '9876543219876499'
290 say 'sub 9876543219876543-44 wrong'
292 ok($I1, 'sub(bigint,integer)')
303 is($S0, '999999000000', 'mul(bigint,bigint)')
308 $P2 = mul $P0, 1000000
309 is($P2, '999999000000', 'mul(bigint,nativeint)')
315 $P0 = '100000000000000000000'
317 $P1 = '100000000000000000000'
323 say 'div 100000000000000000000/100000000000000000000 wrong'
327 $P3 = '10000000000000'
332 say 'div 100000000000000000000/10000000 wrong'
336 $P3 = '10000000000000000000'
340 say 'div 100000000000000000000/10 wrong'
344 $P3 = '-100000000000000000000'
348 say 'div 100000000000000000000/(-1) wrong'
350 ok($I1, 'div(bigint,bigint)')
354 $P0 = '100000000000000000000'
358 $P2 = '10000000000000000000'
361 say 'div 100000000000000000000/10 wrong'
364 $P0 = '100000000000000'
365 $P1 = div $P0, 10000000
369 say 'div 100000000000000/10000000 wrong'
371 ok($I1, 'div(bigint,nativeint)')
375 $P0 = '100000000000000000000'
377 $P3 = new ['Integer']
381 $P2 = '10000000000000000000'
384 say 'div 100000000000000000000/10 wrong'
387 $P0 = '100000000000000'
388 $P4 = new ['Integer']
394 say 'div 100000000000000/10000000 wrong'
396 ok($I1, 'div(bigint,integer)')
400 .sub division_by_zero
403 $P0 = '1000000000000000000000'
405 ## divide by a zero BigInt
411 say 'Failed to throw exception'
416 eq $S0, 'Divide by zero', OK1
419 say ' is wrong exception type'
421 ok($I1, 'div(bigint,bigint 0) throws "Divide by zero" exception')
425 $P0 = '1000000000000000000000'
427 ## modulus by a zero BigInt
433 say 'Failed to throw exception'
438 eq $S0, 'Divide by zero', OK2
441 say ' is wrong exception type'
443 ok($I1, 'mod(bigint,bigint 0) throws "Divide by zero" exception')
447 $P0 = '1000000000000000000000'
449 ## divide by a zero Integer
450 $P2 = new ['Integer']
455 say 'Failed to throw exception'
460 eq $S0, 'Divide by zero', OK3
463 say ' is wrong exception type'
465 ok($I1, 'div(bigint,integer 0) throws "Divide by zero" exception')
469 $P0 = '1000000000000000000000'
471 ## modulus by a zero Integer
472 $P2 = new ['Integer']
477 say 'Failed to throw exception'
481 eq $S0, 'Divide by zero', OK4
484 say ' is wrong exception type'
486 ok($I1, 'mod(bigint,integer 0) throws "Divide by zero" exception')
494 $P0 = '123456789123456789'
496 $P1 = '-123456789123456789'
500 $P0 = '-123456789123456789'
502 $P1 = '123456789123456789'
509 .sub 'get_int_minmax'
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
522 unless $I0 goto end_loop
533 .sub negate_min_integer
538 (min, max) = 'get_int_minmax'()
542 neg neg_min # Use 1-operand form of neg.
543 is(neg_min, max_1, 'negate minimum native integer')
548 $P0 = '-1230000000000000000000'
552 is($S0,'1230000000000000000000','abs negates negative number')
554 is($S0,'-1230000000000000000000','... and original unchanged with 2-arg form')
557 is($S0,'1230000000000000000000','... does not change to positive number')
561 is($S0,'1230000000000000000000','... and in-place works too')
564 .sub absolute_min_integer
570 (min, max) = 'get_int_minmax'()
574 result = abs neg_min # Use 2-operand form of abs.
575 is(result, max_1, 'absolute minimum native integer')
578 .sub overflow_coercion
579 # check libgmp included in Parrot build
581 $P4 = $P0[.IGLOBALS_CONFIG_HASH]
582 $I0 = $P4['intvalsize']
585 print 'Cannot cope with sizeof(INTVAL) == '
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
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
622 print '-bit Integers ['
628 # Checking upper bound by incremental increase
630 $P0 = new ['Integer']
632 $P1 = new ['Integer']
636 eq $S0, 'Integer', k0
638 say "typeof != 'Integer'"
641 eq $S0, $S5, k1 # MaxInt
643 say 'value != MaxInt'
649 say "typeof != 'BigInt'"
652 eq $S0, $S6, k3 # MaxInt+1
654 say 'value != MaxInt+1'
660 say "typeof != 'BigInt'"
663 eq $S0, $S7, k5 # MaxInt+2
665 say 'value != MaxInt+2'
668 # Checking upper bound by increased steps
669 $P0 = new ['Integer']
671 $P2 = new ['Integer']
674 eq $S0, 'Integer', k6
676 say "typeof != 'Integer'"
679 eq $S0, $S5, k7 # MaxInt
681 say 'value != MaxInt'
684 $P2 = new ['Integer']
689 say "typeof != 'BigInt'"
692 eq $S0, $S6, k9 # MaxInt+1
694 say 'value != MaxInt+1'
697 $P2 = new ['Integer']
700 eq $S0, 'BigInt', k10
702 say "typeof != 'BigInt'"
705 eq $S0, $S7, k11 # MaxInt+2
707 say 'value != MaxInt+2'
709 ok($I1, 'integer addition converts MaxInt+1 to BigInt')
711 # Checking lower bound
713 $P0 = new ['Integer']
716 $P2 = new ['Integer']
719 ne $S0, 'Integer', k12
727 $P2 = new ['Integer']
730 ne $S0, 'BigInt', k14
738 $P2 = new ['Integer']
741 ne $S0, 'BigInt', k16
748 is($I1, 0, 'integer addition converts MinInt+(-1) to BigInt')
751 $P0 = new ['Integer']
754 $P2 = new ['Integer']
757 ne $S0, 'Integer', k18
765 $P2 = new ['Integer']
768 ne $S0, 'BigInt', k20
776 $P2 = new ['Integer']
779 ne $S0, 'BigInt', k22
786 is($I1, 0, 'integer subtraction converts MaxInt-(-1) to BigInt')
789 $P0 = new ['Integer']
794 ne $S0, 'BigInt', k24
801 ok($I1, 'integer negation of MinInt converts to BigInt')
804 $P0 = new ['Integer']
809 ne $S0, 'BigInt', k26
816 ok($I1, 'integer abs(MinInt) converts to BigInt')
818 $P0 = new ['Integer']
820 $P1 = new ['Integer']
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')
837 $P0 = '123456789123456789'
848 ok($I0, 'truth and falsehood')
851 # How this next test was originally written in Python:
854 # def __iter__(self):
855 # k, a, b, a1, b1 = 2, 4, 1, 12, 4
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
862 # a, a1 = 10*(a%b), 10*(a1%b1)
863 # d, d1 = a//b, a1//b1
867 # for i in xrange(1, 1001):
880 $P6 = new ['Integer']
883 $P7 = new ['Integer']
886 $P8 = new ['Integer']
889 $P9 = new ['Integer']
892 $P10 = new ['Integer']
920 $P18 = fdiv $P9, $P10
922 ne $P17, $P18, restart
929 $P18 = fdiv $P9, $P10
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
962 $S1 = substr $S0,$I3,1
967 eq $S1, "\r", skip_ws
968 eq $S1, "\n", skip_ws
973 is($I0, $I1, 'Computed 1000 digits of PI (using coroutine)')
977 print ' should have been '
979 print ' at position '
993 ok($I1, 'BUG #34949 gt')
1001 ok($I1, 'BUG #34949 ge')
1003 $P0 = new ['BigInt']
1009 ok($I1, 'BUG #34949 ne')
1011 $P0 = new ['BigInt']
1017 ok($I1, 'BUG #34949 eq')
1019 $P0 = new ['BigInt']
1025 ok($I1, 'BUG #34949 le')
1027 $P0 = new ['BigInt']
1033 ok($I1, 'BUG #34949 lt')
1041 # vim: expandtab shiftwidth=4 ft=pir: