1#!./parrot
2# Copyright (C) 2001-2011, Parrot Foundation.
3
4=head1 NAME
5
6t/pmc/integer.t - Integer basic type
7
8=head1 SYNOPSIS
9
10    % prove t/pmc/integer.t
11
12=head1 DESCRIPTION
13
14Tests the Integer PMC.
15
16=cut
17
18.const string MAXINT = 'MAXINT'
19.const string MININT = 'MININT'
20.const string NO_SYSINFO = 'This test requires sysinfo'
21.const num PRECISION = 0.000001
22
23.sub 'test' :main
24    .include 'test_more.pir'
25    .include 'fp_equality.pasm'
26
27    get_max_min()
28
29    plan(142)
30    test_init()
31    test_basic_math()
32    test_truthiness_and_definedness()
33    test_set_string_native()
34    test_isa()
35    test_interface()
36    test_ne()
37    test_gt()
38    test_ge()
39    test_istrue_isfalse()
40    test_if_unless()
41    test_add()
42    test_sub()
43    test_mul()
44    test_div()
45    test_arithmetic()
46    test_mod()
47    test_neg()
48    test_get_as_base()
49    test_get_as_base10()
50    test_get_as_base_various()
51    test_get_as_base_bounds_check()
52    test_cmp_subclass()
53    test_cmp_RT59336()
54    test_cmp_num()
55
56    $I0 = has_bigint()
57    unless $I0 goto no_bigint
58    test_autopromotion_to_BigInt()
59    test_add_BigInt()
60    test_sub_BigInt()
61    test_mul_BigInt()
62    test_div_BigInt()
63    test_mod_BigInt()
64    test_neg_BigInt()
65    goto done_bigint_tests
66  no_bigint:
67    skip_n_bigint_tests(30)
68  done_bigint_tests:
69.end
70
71# Get INTVAL max and min values from sysinfo only if the sys_ops lib is
72# available and leaving them as zero otherwise (that happens during corestes,
73# for example).
74# The test that needs the values are skipped based on this.
75.sub get_max_min
76    .local string code
77
78    code = <<'CODE'
79.loadlib 'sys_ops'
80.include 'sysinfo.pasm'
81.sub aux_get_max
82    .local int m
83    .local pmc pm
84    m = sysinfo .SYSINFO_PARROT_INTMAX
85    pm = box m
86    set_hll_global 'MAXINT', pm
87    m = sysinfo .SYSINFO_PARROT_INTMIN
88    pm = box m
89    set_hll_global 'MININT', pm
90.end
91CODE
92
93    .local pmc m
94    m = box 0
95    set_hll_global MAXINT, m
96    m = box 0
97    set_hll_global MININT, m
98    .local pmc pircomp
99    push_eh catch
100    pircomp = compreg 'PIR'
101    if null pircomp goto done
102    .local pmc getit
103    getit = pircomp(code)
104    getit()
105    goto done
106  catch:
107    .local pmc ex
108    .get_results(ex)
109    finalize ex
110
111  done:
112    pop_eh
113.end
114
115.sub has_bigint
116    push_eh _dont_have_bigint
117    $P0 = new ['BigInt']
118    pop_eh
119    .return(1)
120  _dont_have_bigint:
121    pop_eh
122    .return(0)
123.end
124
125.sub skip_n_bigint_tests
126    .param int n
127  loop_top:
128    if n == 0 goto _done
129    skip("No BigInt library")
130    n = n - 1
131    goto loop_top
132  _done:
133.end
134
135.sub test_init
136    .local pmc i1, i2
137    i1 = new ['Integer']
138    is(i1, 0, "Default value of Integer is 0")
139    i1 = 42
140    i2 = new ['Integer'], i1
141    is(i2, 42, "Initialize with argument set correct value")
142.end
143
144.sub test_get_as_base_bounds_check
145    throws_substring(<<'CODE', 'base out of bounds', 'get_as_base lower bound check')
146    .sub main :main
147        $P0 = new ['Integer']
148        $P0 = 42
149        $S0 = $P0.'get_as_base'(1)
150        say $S0
151    .end
152CODE
153    throws_substring(<<'CODE', 'base out of bounds', 'get_as_base upper bound check')
154    .sub main :main
155        $P0 = new ['Integer']
156        $P0 = 42
157        $S0 = $P0.'get_as_base'(37)
158        say $S0
159    .end
160CODE
161.end
162
163.sub test_basic_math
164    .local pmc int_1
165    int_1 = new ['Integer']
166    is(int_1, 0, 'Integer PMC creation')
167    int_1 = 1
168    is(int_1, 1, '... set')
169    int_1 += 777777
170    int_1 -= 777776
171    is(int_1, 2, '... add/sub')
172    int_1 *= -333333
173    int_1 /= -222222
174    is(int_1, 3, '... mul/div')
175    inc int_1
176    inc int_1
177    dec int_1
178    is(int_1, 4, '... inc/dec')
179    neg int_1
180    dec int_1
181    neg int_1
182    is(int_1, 5, '... neg')
183
184    $P9 = get_hll_global MININT
185    $I0 = $P9
186    unless $I0 goto skip
187
188    throws_substring(<<'CODE', 'Integer overflow', 'mul integer overflow')
189
190    .sub main :main
191        .include 'errors.pasm'
192        errorson .PARROT_ERRORS_OVERFLOW_FLAG
193        .include 'sysinfo.pasm'
194        $I0 = sysinfo .SYSINFO_PARROT_INTMAX
195
196        $P0 = new ['Integer']
197        $P0 = $I0
198        $P0 *= 2
199    .end
200CODE
201    goto more
202
203  skip:
204    skip(1, NO_SYSINFO)
205
206  more:
207    int_1 = new ['Integer']
208    int_1 = -57494
209    int_1 = abs int_1
210    is(int_1, 57494, 'absolute value, assignment')
211
212    int_1 = new ['Integer']
213    int_1 = 6
214    abs int_1
215    is(int_1, 6, 'absolute value, in-place')
216.end
217
218.sub test_autopromotion_to_BigInt
219    push_eh _dont_have_bigint_library
220    .local pmc bigint_1
221    .local pmc int_1
222
223    int_1 = new ['Integer']
224    bigint_1 = new ['BigInt']
225
226    $P9 = get_hll_global MININT
227    $I0 = $P9
228    unless $I0 goto skip
229
230    int_1 = $I0
231    bigint_1 = int_1 - 1
232
233    dec int_1
234    $P0 = typeof int_1
235    is(int_1, bigint_1, 'dec integer overflow promotion')
236    is($P0, 'BigInt', 'dec integer overflow type check')
237
238    goto _have_bigint_library
239  _dont_have_bigint_library:
240    pop_eh
241
242    # TODO: What should we do here?
243    ok(1, "no bigint library")
244    ok(1, "no bigint library")
245  _have_bigint_library:
246    goto end
247  skip:
248    skip(2, NO_SYSINFO)
249  end:
250.end
251
252.sub test_truthiness_and_definedness
253    .local pmc int_1
254    int_1 = new ['Integer']
255
256    nok(int_1, "A newly created Integer is not true")
257
258    .local int is_defined
259
260    is_defined = defined int_1
261
262    nok(int_1, "A newly created Integer is not defined")
263
264    int_1 = -999999999
265
266    ok(int_1, "-999999999 is true")
267
268    is_defined = defined int_1
269
270    ok(int_1, "-999999999 is defined")
271
272.end
273
274
275.sub test_set_string_native
276    .local pmc pmc1
277    pmc1 = new ['Integer']
278    pmc1 = "-123456789"
279    is(pmc1, -123456789)
280.end
281
282
283.sub test_isa
284    .local pmc pmc1
285    pmc1 = new ['Integer']
286
287    .local int pmc1_is_a
288    pmc1_is_a = isa pmc1, "Integer"
289    isa_ok(pmc1, "Integer")
290.end
291
292.sub test_interface
293    .local pmc pmc1
294    pmc1 = new ['Integer']
295    .local int bool1
296    does bool1, pmc1, "scalar"
297    is(bool1,1)
298    does bool1, pmc1, "integer"
299    is(bool1,1)
300    does bool1, pmc1, "no_interface"
301    is(bool1,0)
302.end
303
304.sub test_ne
305    .local pmc pmc1
306    pmc1 = new ['Integer']
307    .local int int1
308    pmc1 = 10
309    int1 = 20
310    ne pmc1, int1, OK1
311    ok(0)
312    goto next_test
313OK1:
314    ok(1)
315
316next_test:
317
318    int1 = 10
319    ne pmc1, int1, BAD2
320    branch OK2
321BAD2:
322    ok(0)
323    goto fin
324OK2:
325    ok(1)
326fin:
327.end
328
329
330.sub test_gt
331    .local pmc pmc1
332    pmc1 = new ['Integer']
333    .local int int1
334    pmc1 = 10
335    int1 = 5
336    gt pmc1, int1, OK1
337    ok(0)
338    goto next_test1
339OK1:
340    ok(1)
341
342next_test1:
343    int1 = 10
344    gt pmc1, int1, BAD2
345    branch OK2
346BAD2:
347    ok(0)
348OK2:
349    ok(1)
350
351next_test2:
352    int1 = 20
353    gt pmc1, int1, BAD3
354    branch OK3
355BAD3:
356    ok(0)
357    goto fin
358OK3:
359    ok(1)
360fin:
361.end
362
363
364.sub test_ge
365    .local pmc pmc1
366    pmc1 = new ['Integer']
367    .local int int1
368    pmc1 = 10
369    int1 = 5
370    ge pmc1, int1, OK1
371    ok(0)
372    goto next_test1
373OK1:
374    ok(1)
375    int1 = 10
376
377next_test1:
378    ge pmc1, int1, OK2
379    ok(0)
380    goto next_test2
381OK2:
382    ok(1)
383    int1 = 20
384next_test2:
385    ge pmc1, int1, BAD3
386    branch OK3
387BAD3:
388    ok(0)
389    goto fin
390OK3:
391    ok(1)
392fin:
393.end
394
395
396.sub test_istrue_isfalse
397    .local pmc pmc1
398    pmc1 = new ['Integer']
399    .local int int1
400    pmc1 = 10
401    istrue int1, pmc1
402    is(1,int1)
403    isfalse int1, pmc1
404    is(0,int1)
405    pmc1 = 0
406    istrue int1, pmc1
407    is(0,int1)
408    isfalse int1, pmc1
409    is(1,int1)
410.end
411
412
413.sub test_if_unless
414      new $P0, ['Integer']
415      set $P0, 10
416      if $P0, OK1
417      ok(0)
418      goto test1
419OK1:
420      ok(1)
421test1:
422      unless $P0, BAD2
423      branch OK2
424BAD2:
425      ok(0)
426      goto test2
427OK2:
428      ok(1)
429      set $P0, 0
430test2:
431      if $P0, BAD3
432      branch OK3
433BAD3:
434      ok(0)
435      goto test3
436OK3:
437      ok(1)
438test3:
439      unless $P0, OK4
440      ok(0)
441      goto fin
442OK4:
443      ok(1)
444fin:
445.end
446
447.sub test_add_BigInt
448    $P9 = get_hll_global MAXINT
449    $I0 = $P9
450    unless $I0 goto skip
451    new $P0, ['Integer']
452    new $P1, ['BigInt']
453    set $P0, $I0
454    set $P1, $I0
455    add $P0, $P0, 1
456    add $P1, $P1, 1
457    typeof $P2, $P0
458    is($P0, $P1, 'add integer overflow promotion')
459    is($P2, 'BigInt', 'add integer overflow type check')
460
461    new $P0, ['Integer']
462    set $P0, $I0
463    add $P0, 1
464    typeof $P2, $P0
465    is($P0, $P1, 'i_add integer overflow promotion')
466    is($P2, 'BigInt', 'i_add integer overflow type check')
467    goto end
468  skip:
469    skip(4, NO_SYSINFO)
470  end:
471.end
472
473.sub test_add
474   new $P0, ['Integer']
475   set $P0, 5
476   new $P1, ['Integer']
477   set $P1, 10
478   new $P2, ['Integer']
479   add $P2, $P0, $P1
480   set $S0, $P2
481   is($S0,15)
482   set $P0, "20"
483   set $P1, "30"
484   add $P2, $P1, $P0
485   set $S0, $P2
486   is($S0,50)
487
488   new $P0, ['Integer']
489   new $P1, ['Complex']
490   set $P0, 20
491   set $P1, 4
492   add $P0, $P1
493   is($P0, "4+0i", 'add complex number')
494
495   new $P0, ['Integer']
496   new $P1, ['Float']
497   set $P0, 31
498   set $P1, 20.1
499   add $P0, $P1
500   is($P0, 51, 'add DEFAULT')
501
502   new $P0, ['Integer']
503   set $P0, 2
504   add $P0, 3.14159
505   add $P0, 5.75
506   is($P0, 10, 'add_float')
507.end
508
509.sub test_sub_BigInt
510    $P0 = new ['BigInt']
511    $P0 = 424124
512    $P1 = new ['Integer']
513    $P1 = 424125
514    sub $P1, $P1, $P0
515    is($P1, 1, 'BigInt sub (no exception)')
516
517    $P0 = new ['Integer']
518    $P1 = new ['BigInt']
519    $P9 = get_hll_global MININT
520    $I0 = $P9
521    unless $I0 goto skip
522    $P0 = $I0
523    $P1 = $I0
524    sub $P0, $P0, 1
525    sub $P1, $P1, 1
526    typeof $P2, $P0
527    is($P0, $P1, 'subtract overflow promotion')
528    is($P2, 'BigInt', 'subtract overflow type check')
529
530    $P0 = new ['Integer']
531    $P0 = $I0
532    sub $P0, 1
533    typeof $P2, $P0
534    is($P0, $P1, 'i_subtract_int overflow promotion')
535    is($P2, 'BigInt', 'i_subtract_int overflow type check')
536
537    $P0 = new ['Integer']
538    $P2 = new ['Integer']
539    $P0 = $I0
540    $P2 = 1
541    sub $P0, $P2
542    typeof $P3, $P0
543    is($P0, $P1, 'i_subtract overflow promotion')
544    is($P3, 'BigInt', 'i_subtract overflow type check')
545    goto end
546  skip:
547    skip(6, NO_SYSINFO)
548  end:
549.end
550
551.sub test_sub
552    $P0 = new ['Float']
553    $P0 = 3.1
554    $P1 = new ['Integer']
555    $P1 = 10
556    sub $P1, $P1, $P0
557    is($P1, 6.9, 'DEFAULT sub', PRECISION)
558
559    $P0 = new ['Integer']
560    $P0 = 5
561    sub $P0, 4.5
562    is($P0, .5, 'i_subtract_float')
563
564    $P0 = new ['Integer']
565    $P1 = new ['Complex']
566    $P0 = 0
567    $P1 = "4+2i"
568    sub $P0, $P1
569    is($P0, "-4-2i", 'subtract Complex number')
570
571    $P0 = new ['Integer']
572    $P1 = new ['Float']
573    $P0 = 5
574    $P1 = 4.5
575    sub $P0, $P1
576    is($P0, .5, 'subtract DEFAULT multimethod')
577.end
578
579.sub test_mul
580    $P0 = new ['Integer']
581    $P1 = new ['String']
582    $P0 = 1
583    $P1 = "256"
584    mul $P0, $P0, $P1
585    is($P0, 256, 'multiply Integer PMC by String PMC')
586
587    $P1 = new ['Float']
588    $P0 = 2
589    $P1 = 3.14
590    mul $P0, $P0, $P1
591    is($P0, 6, 'multiply Integer PMC by Float PMC')
592
593    $P1 = new ['Integer']
594    $P1 = 4
595    mul $P0, $P1
596    is($P0, 24, 'i_multiply Integer PMC by Integer PMC')
597
598    $P0 = new ['Integer']
599    $P1 = new ['Float']
600    $P0 = 2
601    $P1 = 3.5
602    mul $P0, $P1
603    is($P0, 7, 'i_multiply Integer PMC by DEFAULT')
604
605    $P0 = new ['Integer']
606    $P0 = 2
607    mul $P0, 5.5
608    is($P0, 11, 'i_multiply_float')
609.end
610
611.sub test_mul_BigInt
612    $P0 = new ['Integer']
613    $P1 = new ['BigInt']
614    $P2 = new ['Integer']
615    $P0 = 24
616    $P1 = 2
617    $P2 = 48
618    mul $P0, $P1
619    $I0 = iseq $P0, $P2
620    ok($I0, 'i_multiply Integer PMC by BigInt PMC')
621
622    $P0 = new ['Integer']
623    $P9 = get_hll_global MAXINT
624    $I0 = $P9
625    unless $I0 goto skip
626    $P0 = $I0
627    $P1 = $I0
628    mul $P0, 2
629    mul $P1, 2
630    $P2 = typeof $P0
631    is($P0, $P1, 'i_multiply_int overflow promotion')
632    is($P2, 'BigInt', 'i_multiple_int overflow type check')
633    goto end
634  skip:
635    skip(2, NO_SYSINFO)
636  end:
637.end
638
639.sub test_div_BigInt
640    $P0 = new ['Integer']
641    $P1 = new ['BigInt']
642    $P0 = 50
643    $P1 = 25
644    $P2 = div $P0, $P1
645    $P3 = typeof $P2
646    is($P2, 2, 'divide overflow promotion')
647    is($P3, 'BigInt', 'divide overflow type check')
648
649    $P0 = new ['Integer']
650    $P1 = new ['BigInt']
651    $P0 = 50
652    $P1 = 25
653    div $P0, $P1
654    $P2 = typeof $P0
655    is($P0, 2, 'i_divide overflow promotion')
656    is($P2, 'BigInt', 'i_divide overflow type check')
657
658    $P0 = new ['Integer']
659    $P1 = new ['BigInt']
660    $P0 = 10
661    $P1 = 7
662    $P0 = fdiv $P0, $P1
663    $P2 = typeof $P0
664    is($P0, 1, 'floor_divide overflow promotion')
665    is($P2, 'BigInt', 'floor_divide overflow type check')
666
667    $P0 = new ['Integer']
668    $P1 = new ['BigInt']
669    $P0 = 20
670    $P1 = 9
671    fdiv $P0, $P1
672    $P2 = typeof $P0
673    is($P0, 2, 'i_floor_divide overflow promotion')
674    is($P2, 'BigInt', 'i_floor_divide overflow type check')
675.end
676
677.sub test_div
678    throws_substring(<<'CODE', 'float division by zero', 'divide by 0 (Float PMC)')
679    .sub main :main
680        $P0 = new ['Integer']
681        $P1 = new ['Float']
682        $P0 = 50
683        $P1 = 0
684        $P2 = div $P0, $P1
685        say $P2
686    .end
687CODE
688
689    $P0 = new ['Integer']
690    $P1 = new ['Float']
691    $P0 = 50
692    $P1 = .5
693    div $P0, $P1
694    is($P0, 100, 'i_divide DEFAULT multi')
695
696    throws_substring(<<'CODE', 'float division by zero', 'i_divide by 0 (Float PMC)')
697    .sub main :main
698        $P0 = new ['Integer']
699        $P1 = new ['Float']
700        $P0 = 50
701        $P1 = 0
702        div $P0, $P1
703        say $P0
704    .end
705CODE
706
707    throws_substring(<<'CODE', 'float division by zero', 'floor_divide by 0 (Float PMC)')
708    .sub main :main
709        $P0 = new ['Integer']
710        $P1 = new ['Float']
711        $P0 = 50
712        $P1 = 0
713        $P0 = fdiv $P0, $P1
714        say $P0
715    .end
716CODE
717
718    throws_substring(<<'CODE', 'float division by zero', 'floor_divide by 0 (FLOATVAL)')
719    .sub main :main
720        $P0 = new ['Integer']
721        $P0 = 50
722        $P0 = fdiv $P0, 0.0
723        say $P0
724    .end
725CODE
726
727    $P0 = new ['Integer']
728    $P0 = 22
729    $P0 = fdiv $P0, 7
730    is($P0, 3, 'floor_divide INTVAL')
731
732    throws_substring(<<'CODE', 'float division by zero', 'floor_divide by 0 (INTVAL)')
733    .sub main :main
734        $P0 = new ['Integer']
735        $P0 = 50
736        $P0 = fdiv $P0, 0
737        say $P0
738    .end
739CODE
740
741    $P0 = new ['Integer']
742    $P1 = new ['Float']
743    $P0 = 20
744    $P1 = 2.3
745    fdiv $P0, $P1
746    is($P0, 8, 'i_floor_divide DEFAULT multi')
747
748    throws_substring(<<'CODE', 'float division by zero', 'i_floor_divide by 0 (DEFAULT)')
749    .sub main :main
750        $P0 = new ['Integer']
751        $P1 = new ['Float']
752        $P0 = 50
753        $P1 = 0
754        fdiv $P0, $P1
755        say $P0
756    .end
757CODE
758
759    $P0 = 20
760    fdiv $P0, 7
761    is($P0, 2, 'i_floor_divide INTVAL multi')
762
763    throws_substring(<<'CODE', 'float division by zero', 'i_floor_divide by 0 INTVAL multi')
764    .sub main :main
765        $P0 = new ['Integer']
766        $P0 = 50
767        fdiv $P0, 0
768        say $P0
769    .end
770CODE
771
772    $P0 = 20
773    fdiv $P0, 2.3
774    is($P0, 8, 'i_floor_divide FLOATVAL multi')
775
776    throws_substring(<<'CODE', 'float division by zero', 'i_floor_divide by 0 FLOATVAL multi')
777    .sub main :main
778        $P0 = new ['Integer']
779        $P0 = 50
780        fdiv $P0, 0.0
781        say $P0
782    .end
783CODE
784
785.end
786
787.sub test_arithmetic
788    $P0 = new ['Integer']
789    $P1 = new ['Integer']
790    set $P0, 6
791    set $P1, 2
792
793    add $P2, $P0, $P1
794    is($P2,8)
795    $P2 = add $P0, $P1
796    is($P2,8)
797    sub $P2, $P0, $P1
798    is($P2,4)
799    mul $P2, $P0, $P1
800    is($P2,12)
801    div $P2, $P0, $P1
802    is($P2,3)
803    mod $P2, $P0, $P1
804    is($P2,0)
805.end
806
807.sub test_mod_BigInt
808    $P0 = new ['Integer']
809    $P1 = new ['BigInt']
810    $P0 = 7
811    $P1 = 5
812    $P0 = mod $P0, $P1
813    $P2 = typeof $P0
814    is($P0, 2, 'modulus overflow promotion')
815    is($P2, 'BigInt', 'modulus overflow type check')
816
817    $P0 = new ['Integer']
818    $P1 = new ['BigInt']
819    $P0 = 7
820    $P1 = 5
821    mod $P0, $P1
822    $P2 = typeof $P0
823    is($P0, 2, 'i_modulus overflow promotion')
824    is($P2, 'BigInt', 'i_modulus overflow type check')
825.end
826
827.sub test_mod
828    throws_substring(<<'CODE', 'int modulus by zero', 'modulus by 0 DEFAULT multi')
829    .sub main :main
830        $P0 = new ['Integer']
831        $P1 = new ['Float']
832        $P0 = 7
833        $P1 = 0
834        $P0 = mod $P0, $P1
835        say $P0
836    .end
837CODE
838
839    $P0 = new ['Integer']
840    $P0 = 7
841    $P0 = mod $P0, 4
842    is($P0, 3, 'modulus INTVAL multi')
843
844    throws_substring(<<'CODE', 'int modulus by zero', 'modulus by 0 INTVAL multi')
845    .sub main :main
846        $P0 = new ['Integer']
847        $P0 = 7
848        $P0 = mod $P0, 0
849        say $P0
850    .end
851CODE
852    throws_substring(<<'CODE', 'int modulus by zero', 'modulus by 0 FLOATVAL multi')
853    .sub main :main
854        $P0 = new ['Integer']
855        $P0 = 7
856        $P0 = mod $P0, 0.0
857        say $P0
858    .end
859CODE
860
861    $P0 = new ['Integer']
862    $P1 = new ['Float']
863    $P0 = 7
864    $P1 = 5
865    mod $P0, $P1
866    is($P0, 2, 'i_modulus DEFAULT multi')
867
868    throws_substring(<<'CODE', 'int modulus by zero', 'i_modulus by 0 DEFAULT multi')
869    .sub main :main
870        $P0 = new ['Integer']
871        $P1 = new ['Float']
872        $P0 = 7
873        $P1 = 0
874        mod $P0, $P1
875        say $P0
876    .end
877CODE
878
879    $P0 = new ['Integer']
880    $P0 = 7
881    mod $P0, 4
882    is($P0, 3, 'i_modulus INTVAL multi')
883    $P0 = 7
884    mod $P0, 3.0
885    is($P0, 1, 'i_modulus FLOATVAL multi')
886
887    throws_substring(<<'CODE', 'int modulus by zero', 'i_modulus by 0 INTVAL multi')
888    .sub main :main
889        $P0 = new ['Integer']
890        $P0 = 7
891        mod $P0, 0
892        say $P0
893    .end
894CODE
895    throws_substring(<<'CODE', 'int modulus by zero', 'i_modulus by 0 FLOATVAL multi')
896    .sub main :main
897        $P0 = new ['Integer']
898        $P0 = 7
899        mod $P0, 0.0
900        say $P0
901    .end
902CODE
903.end
904
905.sub test_neg_BigInt
906    $P0 = new ['Integer']
907    $P1 = new ['BigInt']
908
909    $P9 = get_hll_global MININT
910    $I0 = $P9
911    unless $I0 goto skip
912
913    $P0 = $I0
914    $P1 = $I0
915    neg $P1
916
917    $P0 = neg $P0
918    $P2 = typeof $P0
919    is($P0, $P1, 'neg integer overflow promotion')
920    is($P2, 'BigInt', 'neg integer overflow type check')
921    goto end
922  skip:
923    skip(2, NO_SYSINFO)
924  end:
925.end
926
927.sub test_neg
928    $P0 = new ['Integer']
929    $P0 = -3
930    neg $P0
931    is($P0, 3, 'i_neg')
932.end
933
934
935.sub test_get_as_base
936    $P0 = new ['Integer']
937    $P0 = 42
938    $I0 = can $P0, 'get_as_base'
939    ok($I0,'Integers can get_as_base')
940.end
941
942.sub test_get_as_base10
943    $P0 = new ['Integer']
944    $P0 = 42
945
946    $S0 = $P0.'get_as_base'(10)
947    is($S0,42)
948.end
949
950.sub test_get_as_base_various
951    $P0 = new ['Integer']
952    $P0 = 42
953
954    $S0 = $P0.'get_as_base'(2)
955    is($S0,101010)
956
957    $S0 = $P0.'get_as_base'(3)
958    is($S0,1120)
959
960    $S0 = $P0.'get_as_base'(5)
961    is($S0,132)
962
963    $S0 = $P0.'get_as_base'(7)
964    is($S0,60)
965
966    $S0 = $P0.'get_as_base'(11)
967    is($S0,39)
968
969    $S0 = $P0.'get_as_base'(13)
970    is($S0,33)
971
972    $S0 = $P0.'get_as_base'(17)
973    is($S0,28)
974
975    $S0 = $P0.'get_as_base'(19)
976    is($S0,24)
977
978    $S0 = $P0.'get_as_base'(23)
979    is($S0,'1j')
980
981    $S0 = $P0.'get_as_base'(29)
982    is($S0,'1d')
983
984    $S0 = $P0.'get_as_base'(31)
985    is($S0,'1b')
986.end
987
988.sub test_cmp_subclass
989    $P0 = subclass 'Integer', 'Int'
990
991    $P1 = new ['Int']
992    $P1 = 1
993    $P2 = new ['Int']
994    $P2 = 2
995
996    $I0 = cmp $P1, $P2
997    is($I0,-1)
998    $I0 = cmp $P1, $P1
999    is($I0,0)
1000    $I0 = cmp $P2, $P1
1001    is($I0,1)
1002.end
1003
1004.sub test_cmp_RT59336
1005    $P0 = new ['Integer']
1006    $P0 = 2147483600
1007
1008test_10:
1009    if $P0 > -10 goto pass
1010    ok(0)
1011    goto test_1000
1012pass:
1013    ok(1)
1014
1015test_1000:
1016    if $P0 > -1000 goto pass2
1017    ok(0)
1018    goto fin
1019pass2:
1020    ok(1)
1021fin:
1022.end
1023
1024.sub test_cmp_num
1025    $P0 = new ['Integer']
1026    $P1 = new ['String']
1027    $P0 = 23
1028    $P1 = "23.4"
1029
1030    $I0 = cmp_num $P0, $P1
1031    is($I0, -1, 'cmp_num 23(Integer PMC), "23.4"(String PMC) = -1')
1032    $P1 = "23e-2"
1033    $I0 = cmp_num $P0, $P1
1034    is($I0, 1, 'cmp_num 23(Integer PMC), "23e-2"(String PMC) = 1')
1035    $P1 = "23"
1036    $I0 = cmp_num $P0, $P1
1037    is($I0, 0, 'cmp_num 23(Integer PMC), "23"(String PMC) = 0')
1038
1039    $P0 = -32
1040    $P1 = "0"
1041    $I0 = cmp_num $P0, $P1
1042    is($I0, -1, 'cmp_num -32(Integer PMC), "0"(String PMC) = -1')
1043    $P0 = 0
1044    $I0 = cmp_num $P0, $P1
1045    is($I0, 0, 'cmp_num 0(Integer PMC), "0"(String PMC) = 0')
1046    $P0 = 245
1047    $I0 = cmp_num $P0, $P1
1048    is($I0, 1, 'cmp_num 245(Integer PMC), "0"(String PMC) = 1')
1049
1050    $P1 = new ['Float']
1051    $P1 = 2.6
1052    $I0 = cmp_num $P0, $P1
1053    is($I0, 1, 'cmp_num 245(Integer PMC), 2.6(Float PMC) = 1')
1054    $P1 = 553.2
1055    $I0 = cmp_num $P0, $P1
1056    is($I0, -1, 'cmp_num 245(Integer PMC), 553.2(Float PMC) = -1')
1057    $P1 = 245
1058    $I0 = cmp_num $P0, $P1
1059    is($I0, 0, 'cmp_num 245(Integer PMC), 245(Float PMC) = 0')
1060
1061    $P1 = new ['Integer']
1062    $P1 = 300
1063    $I0 = cmp_num $P0, $P1
1064    is($I0, -1, 'cmp_num 245(Integer PMC), 300(Integer PMC) = -1')
1065    $P1 = 2
1066    $I0 = cmp_num $P0, $P1
1067    is($I0, 1, 'cmp_num 245(Integer PMC), 2(Integer PMC) = 1')
1068    $P1 = 245
1069    $I0 = cmp_num $P0, $P1
1070    is($I0, 0, 'cmp_num 245(Integer PMC), 245(Integer PMC) = 0')
1071.end
1072
1073# Local Variables:
1074#   mode: pir
1075#   fill-column: 100
1076# End:
1077# vim: expandtab shiftwidth=4 ft=pir:
1078